与第二个字段相交的 SQL 中的返回字段?
Posted
技术标签:
【中文标题】与第二个字段相交的 SQL 中的返回字段?【英文标题】:Return field in SQL that intersects on a second field? 【发布时间】:2013-03-09 02:38:39 【问题描述】:我正在尝试为特定人员返回具有相交字段的字段。我的意思是
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 查询来做我想做的事。
明确指出,与乔有相同朋友的名字列表。
【问题讨论】:
they would have to match 1 and 2 both.
为什么?我只看到乔的number = 1
..?
GROUP_CONCAT
和 JOIN
本身呢?
@Erwin Brandstetter - 乔和比尔都有 (1,1
) 组合。
你还是忽略了澄清:可以有重复吗? (Joe, Sally)
可以出现多次吗?您的问题初稿有重复...
不,它只会出现一次,他们的友谊是关键,所以关系(Joe,Sally)只会出现一次
【参考方案1】:
没有重复
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 ...
仅在您想要排除拥有 其他 个朋友的人时才需要 Joe 没有。
它从结果中排除了您示例中的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')
【讨论】:
SELECT 1 在 NOT EXISTS 中做了什么 它什么也没做,真的。这就是你写EXISTS
(反)半连接的方式。考虑this related question。另外,既然您已经更改了问题,那么我的第一个查询可能一开始就正确。你的问题只是不清楚确切的条件。可以有重复吗?等等。
所以基本上为了更清楚,列出与乔有相同朋友的人
@user1490083:我为没有重复的表添加了一个更简单的版本,并修复了 GROUP BY
子句中的一个错误 - 以及 having 子句中的另一个错误。
感谢欧文,感谢您的帮助以上是关于与第二个字段相交的 SQL 中的返回字段?的主要内容,如果未能解决你的问题,请参考以下文章
sql server 2000返回在第一个表中但不在第二个表中的数据
Microsoft SQL 查询 - 从第二个表返回最后一条记录