Quando si utilizza un outer join, quindi si utilizza una delle colonne "outer" in un controllo di uguaglianza in WHERE
clausola, converti il tuo join esterno in un join interno. Questo perché la tua condizione che controlla la privacy del post richiede che il post sia presente:
AND p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1)
Quando un outer join sta per produrre una riga che corrisponde a una notifica senza un post, verificherebbe la condizione di cui sopra. Dal momento che il post non c'è, p.privacy
restituirebbe NULL
, "contaminando" entrambi i lati di OR
, ed eventualmente fare in modo che l'intera condizione restituisca false
.
Spostando questa condizione in ON
la condizione del join risolverà il problema:
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
Un altro modo per risolvere questo problema sarebbe aggiungere un IS NULL
condizione al tuo OR
, in questo modo:
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