SQL - 仅匹配 IN 子句中的值(不小于或大于)

SQL - Matching only the values in IN clause (not less or more)

我有以下 ManyToMany table TEAM_USERS 和以下数据:

TEAM_ID     USER_ID
1           10
1           3
1           4
1           11
12          10
12          3
12          4
11          3
11          4
18          10
18          7
18          4
18          11

所以,我想得到 TEAM_ID,它只有两个用户 USER_ID IN (3, 4),在这种情况下是团队 11。但我得到的是团队 1 、11 和 12。我只想要 11 队。

我做了以下代码,但没有得到预期的结果

SELECT  team_id
FROM    team_users 
WHERE   user_profile_id IN (3 , 4)
GROUP   BY team_id
HAVING  COUNT(DISTINCT user_profile_id) = 2;

此查询的结果是:

TEAM_ID
1
11
12

因此,非常感谢您的帮助。

=============== 编辑:列表是唯一的,没有重复项

您的 where 子句在您有机会考虑它们之前过滤掉 user_profile_id 不是 34 的行。您可以将逻辑移至 having 子句,例如:

select team_id
from team_users 
group by team_id
having  
    sum(case when user_profile_id in (3, 4) then 1 else 0 end) = 2
    and sum(case when user_profile not in (3, 4) then 1 else 0 end) = 0

这假定 (team_id, user_profile_id) 个元组在您的数据中是唯一的,如示例数据所示。

将所有过滤移动到 where 子句:

SELECT team_id
FROM team_users 
GROUP BY team_id
HAVING COUNT(*) = 2 AND
       SUM(CASE WHEN user_profile_id IN (3 , 4) THEN 1 ELSE 0 END) = 2;

这会检查是否有两个成员,并且他们是两个指定的成员。此外,这假设没有重复项,这似乎是合理的。

假设列表不是太大,您也可以使用 LISTAGG() 来表示:

SELECT team_id
FROM team_users 
GROUP BY team_id
HAVING LISTAGG(user_profile_id, ',') WITHIN GROUP (ORDER BY user_profile_id) = '3,4';

您可以为 where 子句提供 AND 条件以获得 team_id = 11

的结果
SELECT  team_id
FROM    team_users 
WHERE   user_profile_id IN (3 , 4) AND team_id = 11
GROUP   BY team_id
HAVING  COUNT(DISTINCT user_profile_id) = 2;

我没有类似的测试数据库设置,所以你可能想运行检查一下

将 WHERE 条件移动到 条件聚合

只要组合 team_id/user_profile_id 是唯一的:

select team_id
from team_users 
group by team_id
-- exactly those two and no other
having sum(case when user_profile_id in (3, 4) then 1 else -1 end) = 2