Wanneer u een outer join gebruikt en vervolgens een van de "outer" kolommen gebruikt in een gelijkheidscontrole in de WHERE
clausule, converteert u uw outer join naar een inner join. Dit komt omdat uw conditie die de privacy van een bericht controleert, vereist dat het bericht aanwezig is:
AND p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1)
Wanneer een outer join op het punt staat een rij te produceren die overeenkomt met een melding zonder een bericht, wordt de bovenstaande voorwaarde gecontroleerd. Aangezien het bericht er niet is, p.privacy
zou evalueren tot NULL
, "vervuilt" beide zijden van de OR
, en uiteindelijk de hele voorwaarde te evalueren tot false
.
Deze voorwaarde verplaatsen naar de ON
staat van de join zal het probleem oplossen:
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
Een andere manier om dit op te lossen is het toevoegen van een IS NULL
voorwaarde aan uw OR
, zoals dit:
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