我有三张桌子:
People (pk: ID_PERSON)
Employees (pk: ID_EMPLOYEE)
Meetings (pk: ID_MEETING, fk: ID_PERSON, fk: ID_EMPLOYEE)
我需要根据以下条件从会议中选择人员:“找到遇到Employee1 AND Employee2的所有人”
如果我只想选择一个Employee进行过滤,那么我会执行以下操作:
SELECT ID_PERSON FROM Meetings
WHERE ID_EMPLOYEE=:Employee1
但选择至少遇到两个人的人最有效的方法是什么?我可以想象这样的事情:
SELECT
ID_PERSON
FROM
Meetings
WHERE
ID_EMPLOYEE=:Employee2
AND ID_PERSON IN
(SELECT ID_PERSON FROM Meetings
WHERE ID_EMPLOYEE=:Employee1)
但子查询可能会返回大量记录。有没有更好的方法?是否存在单个查询解决方案?
答案 0 :(得分:1)
可以使用自联接完成。为避免重复,您可以使用distinct。
SELECT
DISTINCT(m1.ID_PERSON)
FROM
Meetings m1, Meetings m2
WHERE
m1.ID_EMPLOYEE=:Employee2
AND
m2.ID_EMPLOYEE=:Employee1
AND
m1.ID_PERSON = m2.ID_PERSON
答案 1 :(得分:1)
这个(常见)问题有各种解决方案。它可以使用EXISTS
子查询来解决:
SELECT
p.id_person
FROM
People AS p
WHERE
EXISTS ( SELECT 1
FROM Meetings AS m
WHERE m.id_person = p.id_person
AND m.id_employee = :Employee1)
AND
EXISTS ( SELECT 1
FROM Meetings AS m
WHERE m.id_person = p.id_person
AND m.id_employee = :Employee2
) ;
...或多个JOIN
到Meetings
表。 (我假设)一个人可以与员工进行多次会面,因此如果您使用联接,则必须有DISTINCT
或GROUP BY
(如@ popovitsj的回答)
另一种解决方案是拥有GROUP BY
和COUNT()
。查询更紧凑,但效率通常较低:
SELECT
id_person
FROM
Meetings AS m
WHERE
id_employee IN (:Employee1, :Employee2)
GROUP BY
id_person
HAVING
COUNT( DISTINCT id_employee ) = 2 ;