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
不是 3
或 4
的行。您可以将逻辑移至 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
我有以下 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
不是 3
或 4
的行。您可以将逻辑移至 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