Vertica

成對交點

  • June 15, 2015

我有一個包含兩列的表,比如說 FirstName 和 LastName。我需要獲取另一個表,對於第一個表中的每一對 FirstName,它都包含一個常見 LastName 的計數。

這在 SQL 中是否可行?

如果這會影響查詢的效率,那麼唯一的姓氏比名字的多得多。

一個玩具範例,輸入:

FirstName, LastName
John, Smith
John, Doe
Jane, Doe

輸出:

FirstName1, FirstName2, CommonLastNames
John, John, 2
John, Jane, 1
Jane, Jane, 1
Jane, John, 1

由於這種關係是自反的和對稱的,所以如果結果只是其中一個三角形(例如,對角線上方的那個)是可以的。

我將使用 MS SQL Server 來執行此操作,因為我手頭有一份副本。我相信大多數專業都會這樣做。

首先是一個帶有數據的樣本表。我使用了一個表變數,但對於任何類型的表都是一樣的。

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

insert @t(FirstName,LastName)
values ('John','Smith'),('John','Doe'),('Jane','Doe');

您可以通過自加入來獲得所有對:

select
   a.FirstName, a.LastName, b.FirstName, b.LastName
from @t as a
cross apply @t as b;

使用避免了為了找到一個子句CROSS APPLY的連接條件而不得不跳過循環。ON

接下來,您需要計算一些東西。這就是該CASE語句的用武之地。 case 為每對名字返回一個整數值,這是計算的值。(如果我正確地閱讀了您的問題,您想要 LastNames 匹配的位置,這就是我的比較。希望如果我錯了,如何修改它是顯而易見的。)

select
   ...
   case
       when a.LastName = b.LastName then 1
       else 0
   end
...etc.

添加一個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;

引用自:https://dba.stackexchange.com/questions/103961