TSQL查找对应的数量

时间:2017-03-29 10:16:54

标签: sql sql-server tsql

我有下表:

SenderName  ReceiverName    NumberOfTime
Ajay          Vijay             1
Anthony       Mark              3
Anthony       John              5
David         Mark              2
David         John              5
David         John              3
David         John              1
John          David             2
John          David             2
John          Anthony           5
Mark          Anthony           1

测试数据:

CREATE TABLE [dbo].[tblMyTempTable](
[SenderName] [varchar](20) NULL,
[ReceiverName] [varchar](10) NULL,
[NumberOfTime] [int] NULL
) ON [PRIMARY]
GO

INSERT [dbo].[tblMyTempTable] 
  ([SenderName], [ReceiverName], [NumberOfTime]) 
VALUES 
  (N'David', N'John', 1)
  ,(N'Mark', N'Anthony', 1)
  ,(N'Ajay', N'Vijay', 1)
  ,(N'John', N'David', 2)
  ,(N'Anthony', N'Mark', 3)
  ,(N'David', N'John', 5)
  ,(N'David', N'John', 3)
  ,(N'John', N'David', 2)
  ,(N'David', N'Mark', 2)
  ,(N'John', N'Anthony', 5)
  ,(N'Anthony', N'John', 5)

我需要找出每对之间的对应关系。例如,安东尼已与约翰联系了5次,约翰已与安东尼联系了5次。所以约翰和安东尼之间的完全对应已经10次了。

同样,大卫已经联系约翰总共9次,约翰已经联系了大卫4次。所以总数将是13.我尝试了很多东西,包括使用子串交换列,重新生成等等。我想知道是否有人有有趣的方法来实现想要的结果。提前谢谢。

3 个答案:

答案 0 :(得分:2)

将最少的名称放在一列中,将更多的名称放到另一列中,这样就可以为每一列聚合。

select 
case when sender_name<receiver_name then sender_name else receiver_name end as name1,
case when sender_name>receiver_name then sender_name else receiver_name end as name2,
sum(numberoftime)
from t
group by case when sender_name<receiver_name then sender_name else receiver_name end,
case when sender_name>receiver_name then sender_name else receiver_name end 

答案 1 :(得分:2)

您可以使用如下查询:

;WITH CTE AS (
   SELECT IIF(SenderName < ReceiverName, SenderName, ReceiverName) AS first_name,
          IIF(SenderName >= ReceiverName, SenderName, ReceiverName) AS second_name,
          NumberOfTime
   FROM tblMyTempTable 
)
SELECT first_name, second_name, SUM(NumberOfTime) AS total_times
FROM CTE
GROUP BY first_name, second_name

该查询使用的CTE包含表格的版本,其中SenderNameReceiverName按字母顺序排序。

Demo here

答案 2 :(得分:1)

使用子查询而不是CTE对其他答案略有不同:

SELECT 
    LowName, HighName, SUM(NumberOfTime) TotalNumberOfTime
FROM 
    (
        SELECT
            CASE
                WHEN SenderName < ReceiverName THEN SenderName
                ELSE ReceiverName
            END LowName,
            CASE
                WHEN SenderName > ReceiverName THEN SenderName
                ELSE ReceiverName
            END HighName,
            NumberOfTime
        FROM
            tblMyTempTable
    ) tblMyTempTableWithSortedNames
GROUP BY
    LowName, HighName