我正在尝试返回具有特定人员相交字段的字段。我的意思是
Name Friend
---- -----
Joe Sally
Joe Bill
Mary Sally
Mary Michael
Mike Joe
Bill Bill
Bill Sally
Gil Sally
Gil Bill
Gil David
说,我们想要与Joe的第二列匹配的人员列表,他们必须匹配Sally和Bill。所以只有比尔符合这个标准,因为玛丽有一个,但她没有比尔。吉尔有莎莉和比尔,但他也有大卫。所以只有比尔才能归还。我认为INTERSECT
的某些内容会起作用,因为它会返回常见的字段,但我认为这并不能说明有更多的字段。不确定如何编写SQL查询来执行我想要的操作。
清楚地说明了与Joe拥有完全相同的朋友的名单。
答案 0 :(得分:0)
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 relation
如果可能存在重复项(例如问题的第一稿),事情会变得复杂一些:
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')