Mysql
 sql >> база данни >  >> RDS >> Mysql

Присъединете се към няколко таблици, като запазите NULL

Когато използвате външно присъединяване и след това използвате една от "външните" колони в проверка за равенство в WHERE клауза, вие преобразувате вашето външно съединение във вътрешно съединение. Това е така, защото вашето условие, което проверява поверителността на публикацията, изисква публикацията да е там:

AND p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1)

Когато външно присъединяване е на път да създаде ред, който съответства на известие без публикация, то ще провери горното условие. Тъй като публикацията не е там, p.privacy ще се оцени на NULL , "замърсявайки" двете страни на OR и в крайна сметка накара цялото условие да се оцени на false .

Преместване на това условие в ON състоянието на присъединяването ще реши проблема:

SELECT
  u.username AS sender,
  ux.username AS receiver,
  p.id
FROM notifications n
JOIN follows f ON (n.user_id = f.tofollow_id)
JOIN follows fr ON (n.tonotify_id = fr.tofollow_id)
JOIN user u ON (u.id = n.user_id)
JOIN user ux ON (ux.id = n.tonotify_id)
LEFT JOIN posts p ON (n.posts_id = p.id)
                 AND (p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1))
WHERE f.user_id = 1
  AND fr.user_id = 1
  AND f.status = 1
ORDER BY n.id DESC

Друг начин да поправите това би било добавянето на IS NULL условие към вашето OR , като това:

SELECT
  u.username AS sender,
  ux.username AS receiver,
  p.id
FROM notifications n
JOIN follows f ON (n.user_id = f.tofollow_id)
JOIN follows fr ON (n.tonotify_id = fr.tofollow_id)
JOIN user u ON (u.id = n.user_id)
JOIN user ux ON (ux.id = n.tonotify_id)
LEFT JOIN posts p ON (n.posts_id = p.id)
WHERE f.user_id = 1
  AND fr.user_id = 1
  AND f.status = 1
  AND (p.privacy IS NULL OR p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1))
ORDER BY n.id DESC


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. изграждане на ролеви приложения

  2. Най-добра практика за PHP/MySQL система за назначаване/резервиране

  3. MySQL DATE_FORMAT '%M' за кратък месец?

  4. MySQL:Групиран първичен ключ с InnoDB

  5. Ограничете стойността на MySQL тип данни до конкретен диапазон (за предпочитане не ENUM)