没有重复
SELECT p2.name
FROM people AS p1
JOIN people AS p2 ON p2.number = p1.number
AND p2.name <> p1.name -- exclude self-join
WHERE p1.name = 'Joe'
AND NOT EXISTS (
SELECT 1
FROM people p3
WHERE p3.name = p2.name
AND p3.number <> p1.number
)
GROUP BY p2.name
HAVING count(*) = (SELECT count(*) FROM people WHERE name = 'Joe')
AND NOT EXISTS ...
仅当您要排除拥有乔没有的其他朋友的人时,才需要最后一个条件。它在您的示例中从结果中
排除。Gil
这是关系除法的一个特例(带有自引用表)。您可以在此相关答案中找到一整套查询技术:
How to filter SQL results in a has-many-through relationship
有重复
如果可能有重复项(例如在您的问题初稿中),事情会变得有点复杂:
WITH p AS (
SELECT name, number, count(*) AS ct
FROM people
GROUP BY name, number
)
SELECT p2.name
FROM p AS p1
JOIN p AS p2 ON p2.number = p1.number
AND p2.ct = p1.ct
AND p2.name <> p1.name -- exclude self-join
WHERE p1.name = 'Joe'
AND NOT EXISTS (
SELECT 1
FROM p p3
WHERE p3.name = p2.name
AND p3.number <> p1.number
)
GROUP BY p2.name
HAVING count(*) = (SELECT count(*) FROM p WHERE name = 'Joe')