Когато използвате външно присъединяване и след това използвате една от "външните" колони в проверка за равенство в 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