Quando você usa uma junção externa e, em seguida, usa uma das colunas "externas" em uma verificação de igualdade no
WHERE
cláusula, você converte sua junção externa em uma junção interna. Isso ocorre porque sua condição que verifica a privacidade da postagem exige que a postagem esteja lá:AND p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1)
Quando uma junção externa está prestes a produzir uma linha que corresponde a uma notificação sem uma postagem, ela verifica a condição acima. Como a postagem não está lá,
p.privacy
avaliaria para NULL
, "contaminando" ambos os lados do OR
, e eventualmente fazendo com que toda a condição seja avaliada como false
. Movendo esta condição para
ON
condição da junção irá corrigir o 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
Outra maneira de corrigir isso seria adicionar um
IS NULL
condição para o seu OR
, assim: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