0

我有两张桌子:

Table "contact"

id  | customer_id
----+------------- 
1   | 123
2   | 123
3   | 123
4   | 888

Table "user_contact"

user_id | contact_id
--------+------------
456     | 1
456     | 2
789     | 3
999     | 4

要选择 customer_id 为 123存在于456 中user_contact的所有联系人user_id,我可以:

SELECT
    contact.id
FROM
    contact JOIN user_contact ON
        contact.id = user_contact.contact_id
WHERE
    contact.customer_id = 123 AND
    user_contact.user_id = 456

如何选择所有具有customer_id123 但存在于user_contact456user_id的联系人?

试:

SELECT
    contact.id
FROM
    contact JOIN user_contact ON
        contact.id = user_contact.contact_id
WHERE
    contact.customer_id = 123 AND
    user_contact.user_id != 456

显然不起作用,因为它为每个具有 != 456 的行contact返回user_contact一行user_id

4

2 回答 2

4

您可以使用简单的LEFT JOIN并检查结果user_contact部分是否不存在(即。IS NULL);

SELECT c.* 
FROM contact c
LEFT JOIN user_contact uc ON c.id = uc.contact_id AND uc.user_id='456'
WHERE c.customer_id = '123' AND uc.contact_id IS NULL

一个用于测试的 SQLfiddle

于 2013-08-15T04:29:14.990 回答
1

这通常最好使用 NOT EXISTS 相关子查询来解决,因为性能并不那么依赖于每个父项的子记录数。

SELECT c.* 
FROM   contact c
where  c.customer_id = '123' and
       not exists (
         select null
         from   user_contact uc
         where  c.id       = uc.contact_id and
                uc.user_id = '456')

这将使用半连接,在找到单个子记录后停止。

于 2013-08-15T07:24:11.927 回答