我有一个包含以下数据的多对多映射表。
ID Person Role
-----------------------------------------------------
1 P1 R1
2 P1 R2
3 P1 R3
4 P2 R1
5 P2 R3
6 P2 R5
7 P3 R3
8 P4 R1
9 P4 R2
10 P4 R3
11 P4 R4
12 P4 R5
13 P5 R1
14 P5 R2
15 P5 R3
我想只过滤角色R1,R2,R3的人。具有唯一角色R1,R2,R3的正确人员是P1和P5。
以下查询也会返回角色为R1,R2,R3,R4的人。
SELECT PERSON
FROM RMS.PERSONROLE
WHERE role IN ('R1', 'R2','R3')
GROUP
BY PERSON HAVING COUNT(ROLE)=3;
Expected Output
----------------------
Person
----------------------
P1
P5
答案 0 :(得分:1)
select Person
from Table1
group by
Person
having group_concat(role order by role) = 'R1,R2,R3'
答案 1 :(得分:1)
要考虑的事情......
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(person INT NOT NULL
,role INT NOT NULL
,PRIMARY KEY(person,role)
);
INSERT INTO my_table VALUES
(1,101),
(1,102),
(1,103),
(2,101),
(2,103),
(2,105),
(3,103),
(4,101),
(4,102),
(4,103),
(4,104),
(4,105),
(5,101),
(5,102),
(5,103);
SELECT person
, COUNT(*)x
, SUM(role IN(101,102,103))y
FROM my_table
GROUP
BY person;
+--------+---+------+
| person | x | y |
+--------+---+------+
| 1 | 3 | 3 |
| 2 | 3 | 2 |
| 3 | 1 | 1 |
| 4 | 5 | 3 |
| 5 | 3 | 3 |
+--------+---+------+
答案 2 :(得分:1)
假设(person,role)
元组在表中是唯一的,我们可以这样做:
SELECT p.PERSON
FROM RMS.PERSONROLE p
GROUP
BY p.PERSON
HAVING 3 = SUM(IF(p.role IN ('R1','R2','R3'),1,0)
AND 3 = SUM(1)
如果没有唯一性的保证,我们可以稍微调整一下来计算不同的角色值
SELECT p.PERSON
FROM RMS.PERSONROLE p
GROUP
BY p.PERSON
HAVING 3 = COUNT(DISTINCT IF(p.role IN ('R1','R2','R3'),p.role,NULL))
AND 3 = COUNT(DISTINCT p.role)
修改强>
上面的答案是针对MySQL的。一个更易于移植的ANSI标准兼容版本,用适当的IF()
表达式替换MySQL CASE
函数。
SELECT p.PERSON
FROM RMS.PERSONROLE p
GROUP
BY p.PERSON
HAVING 3 = COUNT(DISTINCT CASE WHEN p.role IN ('R1','R2','R3') THEN p.role END)
AND 3 = COUNT(DISTINCT p.role)
答案 3 :(得分:0)
此查询应该有效:
SELECT PERSON
FROM PERSONROLE
WHERE PERSON NOT IN
(
SELECT PERSON FROM PERSONROLE WHERE role NOT IN('R1', 'R2','R3')
)
GROUP BY PERSON HAVING COUNT(ROLE)=3;
或者这可能更好
SELECT p.PERSON FROM PERSONROLE p
LEFT JOIN
(
SELECT PERSON FROM PERSONROLE WHERE role NOT IN('R1', 'R2','R3')
) a on p.PERSON = a.person
WHERE a.person is null
GROUP BY PERSON HAVING COUNT(ROLE)=3;
答案 4 :(得分:0)
我只是排除了您不想要的roles
:
SELECT P.PERSON
FROM RMS.PERSONROLE P
WHERE NOT EXISTS (SELECT 1
FROM RMS.PERSONROLE
WHERE Person = P.Person AND role IN ('R4', 'R5')
);
但是,这可能无法提供您想要的结果。所以,我会选择GROUP BY
条款
SELECT PERSON
FROM RMS.PERSONROLE
WHERE role IN ('R1', 'R2','R3')
GROUP BY PERSON
HAVING COUNT(DISTINCT ROLE) = 3;