Khi bạn sử dụng một phép nối bên ngoài, rồi sử dụng một trong các cột "bên ngoài" trong kiểm tra bình đẳng trong WHERE
, bạn chuyển đổi phép nối bên ngoài của mình thành phép nối bên trong. Điều này là do điều kiện của bạn để kiểm tra quyền riêng tư của bài đăng yêu cầu bài đăng phải ở đó:
AND p.privacy = 1 OR (p.privacy = 2 AND fr.fstatus = 1)
Khi một liên kết ngoài sắp tạo ra một hàng tương ứng với một thông báo mà không có bài đăng, nó sẽ kiểm tra điều kiện ở trên. Vì bài đăng không có ở đó, p.privacy
sẽ đánh giá thành NULL
, "làm ô nhiễm" cả hai mặt của OR
và cuối cùng làm cho toàn bộ điều kiện được đánh giá là false
.
Di chuyển điều kiện này sang ON
điều kiện tham gia sẽ khắc phục sự cố:
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
Một cách khác để khắc phục điều này là thêm IS NULL
điều kiện với OR
của bạn , như thế này:
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