外部結合を使用してから、WHERE
の等価性チェックで「外部」列の1つを使用する場合 節では、外部結合を内部結合に変換します。これは、投稿のプライバシーをチェックする条件により、投稿がそこにある必要があるためです:
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