选择未链接到另一个表的行

时间:2017-03-29 16:28:53

标签: mysql sql

我有一个名为' messages'的表格,其中包含sender_idrecipient_idmessage列(消息文本)和{{1} (一个标志,指示消息是否被发送给它的人读取。

我正在实施阻止用户的选项,因此添加了一个名为readbyrecipient的表格,列block(阻止用户)和blocker_id(被阻止的用户) )。所有blockee_id列都链接到我的*_id表。

我正在尝试获取未被收件人阻止的用户发送的所有未读邮件。以下是我一直在使用的查询:

users

这不会返回任何行,即使我知道A.recipient_id中指定的用户ID是指来自未被阻止的用户的一条未读消息的用户。我尝试删除查询中的SELECT A.* FROM messages A, block B WHERE A.recipient_id = 18 AND A.readbyrecipient = 0 AND NOT ( B.blocker_id = A.recipient_id AND B.blockee_id = A.sender_id ) 子句,但它仍然返回零行,直到我从查询的SELECT部分​​删除AND NOT,因此我不确定问题是否与block B子句或WHERE子句。

提前致谢!

2 个答案:

答案 0 :(得分:1)

您可以使用左连接找到所有没有匹配记录的记录,然后在where子句中指定该表中的字段必须为null。仅对没有匹配的记录为真。

SELECT 
    A.*
FROM `messages` A
LEFT JOIN `BLOCK` B
ON B.`blockee_id` = a.`sender_id` OR B.`blockee_id` = a.`recipient_id`
WHERE b.`blockee_id` is NULL;

答案 1 :(得分:1)

您需要以下其中一项:

1)LEFT JOIN。请不要使用您使用的旧crummy JOIN语法,因为它不允许LEFT JOIN并且更难阅读。

SELECT 
    A.* 
FROM 
    messages A
    LEFT JOIN block B ON 
        (B.blocker_id = A.recipient_id AND B.blockee_id = A.sender_id)
WHERE 
    A.recipient_id = 18
    AND B.blocker_id IS NULL

注意“B.blocker_id IS NULL”表示“LEFT JOIN未根据JOIN条件找到行”这是您想要的。阅读LEFT OUTER JOIN。

2)好旧不存在

SELECT * FROM messages A
WHERE NOT EXISTS(
    SELECT * FROM block 
    WHERE B.blocker_id = A.recipient_id AND B.blockee_id = A.sender_id
)
WHERE A.recipient_id = 18

3)NOT IN不适用于此,因为我们有2列要测试。