成对交叉点

And*_*nis 4 vertica

我有一个包含两列的表,比如说名字和姓氏。我需要另一个表,其中对于第一对中的每一对名字,都包含共同姓氏的计数。

这在 SQL 中可行吗?

如果姓氏的唯一性会影响查询的效率,则姓氏的唯一性比名字的唯一性要多得多。

一个玩具示例,输入:

FirstName, LastName
John, Smith
John, Doe
Jane, Doe
Run Code Online (Sandbox Code Playgroud)

输出:

FirstName1, FirstName2, CommonLastNames
John, John, 2
John, Jane, 1
Jane, Jane, 1
Jane, John, 1
Run Code Online (Sandbox Code Playgroud)

由于这种关系是自反且对称的,因此如果结果只是三角形之一(例如,对角线上方的三角形)也没关系。

Mic*_*een 5

我将使用 MS SQL Server 来执行此操作,因为我手头有一份副本。我相信大多数专业都会这样做。

首先是一个包含数据的示例表。我使用表变量,但它对于任何类型的表都是相同的。

declare @t table (FirstName char(10), LastName char(10));

insert @t(FirstName,LastName)
values ('John','Smith'),('John','Doe'),('Jane','Doe');
Run Code Online (Sandbox Code Playgroud)

您可以通过自连接获得所有对:

select
    a.FirstName, a.LastName, b.FirstName, b.LastName
from @t as a
cross apply @t as b;
Run Code Online (Sandbox Code Playgroud)

使用CROSS APPLY可以避免为子句寻找连接条件的麻烦ON

接下来你需要一些东西来计算。这就是CASE语句的用武之地。 case 返回每对名字的整数值,这就是被计数的值。(如果我正确地阅读你的问题,你想要姓氏匹配的地方,这就是我所进行的比较。希望如果我错了,如何修改它是显而易见的。)

select
    ...
    case
        when a.LastName = b.LastName then 1
        else 0
    end
...etc.
Run Code Online (Sandbox Code Playgroud)

添加一个SUM()andGROUP BY就可以得到答案:

select
    a.FirstName,
    b.FirstName,
    sum(
    case
        when a.LastName = b.LastName then 1
        else 0
    end
    ) as CommonLastNames
from @t as a
cross apply @t as b
group by a.FirstName, b.FirstName;
Run Code Online (Sandbox Code Playgroud)