查询排除某个表中的行

时间:2013-11-12 17:43:12

标签: python sql postgresql

我有三个表:userscontactsgroups。我想查找用户的所有联系人,然后从这些选定的联系人中,我想要排除那些在group_id表中找到特定groups的用户的联系人。

我的groups表的结构如下:

id (primary key)
group_id (a foreign key to a table contain general group info)
user_id (a foreign key to the users table)

我的contacts表的结构如下:

id (primary key)
user_id (a foreign key to the `users` table of the user who added the contact)
contact_id (a foreign key to the `users` table of the added contact)

我当前的,不工作的查询是这样的:

"""SELECT c.*, u.*
   FROM contacts c
       LEFT JOIN groups g ON c.contact_id = g.user_id
       INNER JOIN users u on u.id = c.contact_id
   WHERE c.user_id = %s AND
       <not sure what further constraints to place on query>""", (user_id, group_id)

根据我的理解,LEFT JOIN肯定是不正确的,并且鉴于它不正确,我还没有在WHERE子句中添加任何更多约束。

实现这一目标的最佳方法是什么? 谢谢。

1 个答案:

答案 0 :(得分:1)

假设LEFT JOIN是正确的,并且您想要包含不属于任何群组的联系人,您可以尝试以下查询:

select 
    c.*,
    u.*
from users u
    join contacts c
        on u.id = c.user_id
    left join groups g
        on c.contact_id = g.user_id
where
    c.user_id = %s
    and g.group_id not in (<your groups here>)

您的组列表将是以逗号分隔的标识符列表。我不知道PostgreSQL python驱动程序是否包含任何可以轻松格式化的功能,但这就是主意。

要在评论中回答您的第二个问题(如何在排除的群组中获得没有群组和联系人的联系人),您可能需要使用联盟:

select 
    c.*,
    u.*
from users u
    join contacts c
        on u.id = c.user_id
    left join groups g
        on c.contact_id = g.user_id
where
    c.user_id = %s
    and g.group_id is null
union
select 
    c.*,
    u.*
from users u
    join contacts c
        on u.id = c.user_id
    join groups g
        on c.contact_id = g.user_id
where
    c.user_id = %s
    and g.group_id = %d