Når du bruger en ydre joinforbindelse og derefter bruger en af de "ydre" kolonner i en lighedskontrol i WHERE
klausul, konverterer du din ydre join til en indre join. Dette skyldes, at din tilstand, der kontrollerer postens privatliv, kræver, at posten er der:
AND p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1)
Når en ydre joinforbindelse er ved at producere en række, der svarer til en notifikation uden et indlæg, vil den kontrollere ovenstående betingelse. Da indlægget ikke er der, p.privacy
ville evaluere til NULL
, "forurener" begge sider af OR
, og til sidst at få hele tilstanden til at evaluere til false
.
Flytter denne tilstand til ON
tilstanden af joinforbindelsen løser problemet:
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
En anden måde at løse dette på ville være at tilføje en IS NULL
tilstand til din OR
, sådan her:
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