我实际上并不需要以下查询,但我醒过这个理论问题"我很难搞清楚。假设我有三个表:用户表,组表和users_groups表,它是多对多的。因此,如果一个用户属于第1组和第2组,则每个用户将有两个不同的行。
现在,假设有很多组,我该如何具体选择属于第2组和第3组的用户?例如?
我沿着这些方向尝试了一些东西,但它显示为空:
SELECT * FROM `users_groups` GROUP BY user_id HAVING group_id = 2 AND group_id = 3
我想这假设两个组都在同一行,这显然不会起作用。我该怎么做?
编辑:两种变体如何:用户必须只在这两个组中,并且用户必须至少在这两个组中?
答案 0 :(得分:2)
SELECT *
FROM users_groups
GROUP BY user_id
WHERE group_id IN (2,3)
HAVING COUNT(1) = 2
这当然假设{user_id
,group_id
}是唯一的(并且没有其他列可以向计数添加其他行)。否则你可以明确地确保这一点:
SELECT *
FROM users_groups
GROUP BY user_id
WHERE group_id IN (2,3)
HAVING COUNT(DISTINCT group_id) = 2
这两组中只有稍微复杂一些。你可以这样做:
SELECT *
FROM users_groups g1
GROUP BY user_id
WHERE group_id IN (2,3)
AND NOT EXISTS
(
SELECT 1
FROM users_groups AS g2
WHERE g2.user_id = g1.user_id
AND group_id NOT IN (2,3)
)
HAVING COUNT(1) = 2
或者,
SELECT *
FROM users_groups g1
GROUP BY user_id
HAVING COUNT(1) = 2
AND SUM(CASE WHEN group_id IN (2,3) THEN 1 ELSE 0 END) = 2
在第2组和第3组中,总共超过2组:
SELECT *
FROM users_groups g1
GROUP BY user_id
HAVING SUM(CASE WHEN group_id IN (2,3) THEN 1 ELSE 0 END) = 2
AND COUNT(1) > 2
答案 1 :(得分:2)
问题称为Relational Division
。
SELECT a.ID, a.Name
FROM users a
INNER JOIN users_groups b
ON a.ID = b.UserID
INNER JOIN groups c
ON b.group_ID = c.ID
WHERE c.Name IN ('grp2', 'grp3')
GROUP BY a.ID, a.Name
HAVING COUNT(DISTINCT c.Name) = 2
如果DISTINCT
上的唯一约束不是针对每个用户强制执行,则在以下查询中使用 Name
,否则HAVING COUNT(*) = 2
就足够了。
答案 2 :(得分:1)
SELECT *, COUNT(*) FROM `users_groups`
WHERE group_id IN (2,3)
GROUP BY user_id HAVING COUNT(*) > 1
答案 3 :(得分:0)
用户必须仅属于第2组和第3组:
SELECT *, group_concat(group_id ASC) gui
FROM users_groups
GROUP BY user_id
HAVING gui="2,3"
答案 4 :(得分:0)
SELECT user_id FROM(select * from users_groups where group_id = 2)grp 1,(select * from users_groups where group_id = 3)grp2 其中grp1.user_id = grp2.user_id