2016-12-08 68 views
0

我试图建构上表示许多一对多的关系,三个表的查询:一个很多的具体的过滤一对多的关系

  • 用户
  • user_groups

我需要查询属于已定义的组数组成员的用户,但如果他们是任何其他组的成员,则不要将它们包括在结果中。

所以我想要只在“groupA”,“groupD”和“groupZ”中的用户,但是如果他们是“groupB”的成员,那么不要在查询结果中返回它们。

我知道这个部分:

SELECT user.name 
FROM user 
JOIN user_groups on user_groups.user_id = user.id 
JOIN groups on user_groups.group_id = group.id 

但我不知道怎么写查询返回我想确切的结果。我应该提到目标数据库是一个oracle数据库,如果这很重要的话。

回答

0

假设groups.name是标识组的列。

SELECT user.name 
FROM user 
JOIN user_groups on user_groups.user_id = user.id 
JOIN groups on user_groups.group_id = group.id 
WHERE groups.name in ("GroupA", "GroupD", "GroupZ") 
0

having中使用过滤器来检查特定组中的用户存在。

SELECT user.name 
FROM user 
JOIN user_groups on user_groups.user_id = user.id 
JOIN groups on user_groups.group_id = group.id 
GROUP BY user.name 
HAVING COUNT(CASE WHEN user_groups.group_id='groupB' THEN user_groups.group_id END) = 0 
AND COUNT(DISTINCT CASE WHEN user_groups.group_id IN ('groupA','groupD','groupZ') THEN user_groups.group_id END) = 3 
+0

我去阅读不同的需求 - 用户必须在一个,两个或三个组A,d和Z(不一定全部三个)。当然,这简化了查询。 – mathguy

+0

@mathguy ..你可能是对的..我在等待op的澄清,因为这个问题并不完全清楚。 –

0

它比较难看,但我会用,,,,

SELECT * 
FROM user 
WHERE id IN (
    SELECT user_id 
    FROM user_groups 
    GROUP BY user_id 
    HAVING 
    3=SUM (DECODE(group_id, 'GroupA', 1, 'GroupB', 1, 'GroupC', 1, 0)) 
    AND 
    0=SUM (DECODE(group_id, 'GroupA', 0, 'GroupB', 0, 'GroupC', 0, 1)) 
)