5

我有 4 张桌子

    users
    |  id  |Username|
    |   1  |  John  |
    |   2  |  Mike  |
    |   3  |  Alex  |

    user_contacts
    | user_id  |contact_id|
    |   1      |    2     |
    |   1      |    3     |
    |   2      |    3     |

    contact_groups
    | id  |  Group name  |
    |  1  |    Group 1   |  
    |  2  |    Group 2   |
    |  3  |    Group 3   |

    user_contact_groups
    | user_id  |contact_group_id|
    |   1      |    1           |
    |   1      |    2           |
    |   3      |    2           |

id 喜欢做的是拉出属于联系人组 1 和 3 的用户或用户 1 的联系人(在 table:user_contacts 中)。下面是代码,但它返回查询为空

SELECT DISTINCT a.* from  users as a 
WHERE EXISTS (SELECT * FROM user_contacts as b 
    WHERE b.user_id = 1) OR 
    (a.id IN (select c.user_id 
         FROM user_contact_groups as c 
            WHERE c.contact_group_id IN (1,3)));
4

2 回答 2

6

这就是我的做法,应该是最理想的:

SELECT DISTINCT u.*
FROM users u
LEFT OUTER JOIN user_contacts c ON u.id = c.contact_id 
    AND c.user_id = 1
LEFT OUTER JOIN user_contact_groups g ON u.user_id = g.user_id 
    AND g.contact_group_id IN (1,3)
WHERE c.id IS NOT NULL OR g.id IS NOT NULL

如果你想使用 EXISTS,你当然可以转过来,但是查询可能无法使用索引(你可以删除这个查询的 DISTICT):

SELECT *
FROM users u
WHERE EXISTS
(
    SELECT 1
    FROM user_contacts c 
    WHERE c.contact_id = u.id
    AND c.user_id = 1
)
OR EXISTS
(
    SELECT 1
    FROM user_contact_groups g 
    WHERE g.user_id = u.user_id
    AND g.contact_group_id IN (1,3)
)

我建议做一个解释,看看哪一个更适合你的 RDBMS。

于 2012-12-20T02:38:18.657 回答
3

你可以做左连接,而不是做子查询

SELECT DISTINCT a.*
FROM users as a
LEFT JOIN user_contacts as b ON a.id = b.user_id AND a.id = 1
LEFT JOIN user_contact_groups as c on c.user_id = a.id AND c.contact_group_id IN (1,3)
WHERE b.user_id IS NOT NULL OR c.user_id IS NOT NULL

我面前没有 SQL 来测试它,但我认为它会得到正确的结果

于 2012-12-20T02:36:29.700 回答