T-SQL 查找呼叫次数最多的人以及他呼叫过的人

T-SQL Finding person with most calls and to who he has called

我的目标是找到通话时间最长的人,显示通话时间、phone号码和人名、姓氏。

一切都必须在一个查询中完成。

我不明白如何处理的部分是,我能够通过 SubscriberID 找到最长的呼叫,但我无法显示它到底是哪个 phone 号码,因为如果我做 max () 并将 SubscriberID 与 AdresseeNumber 分组,我得到所有号码和所有电话。

我有三张表。

NetworkP2P、订阅者和个人。

NetworkP2P有以下数据为例:

NetworkP2P
SubscriberID | ServiceID | AddresseeNumber | CallStart               | CallEnd
1                  1         613-555-0160    2014-08-02 08:30:24.000   2014-08-02 08:45:23.000           
1                  2         614-545-0130    2014-08-02 08:30:24.000   2014-08-02 08:30:24.000
1                  2         653-535-0120    2014-08-02 08:30:24.000   2014-08-02 08:30:24.000
2                  2         653-563-0312    2014-08-02 08:30:24.000   2014-08-02 08:30:24.000
2                  2         613-645-0160    2014-08-02 08:30:24.000   2014-08-02 08:45:24.000
3                  2         613-812-0160    2014-08-02 08:30:24.000   2014-08-02 08:45:24.000
3                  2         613-958-0160    2014-08-02 08:30:24.000   2014-08-02 08:45:24.000
4                  1         613-492-0160    2014-08-02 08:30:24.000   2014-08-02 08:45:24.000



Subscriber
SubscriberID | PersonID
1                 1
2                 1
3                 2
4                 3



Person
PersonID | Name | LastName
1          John    Michael
2          Adam    Savage
3          George   Good

此查询将显示所有呼叫并按所有呼叫的最大值排序。我将如何首先将 phone 号码添加到已选择的号码?此外,之后,如何通过名称和姓氏指定订阅者 ID?

SELECT P2P.SubscriberID , max(DATEDIFF(minute, CallStart, CallEnd)) as 'TimeCall'
FROM dbo.NetworkP2P AS P2P
WHERE ServiceID IN(1,2)
GROUP BY p2p.SubscriberID
ORDER BY P2P.SubscriberID ASC

您可以使用 window 函数(如 row_number())根据调用时间对行进行排名,然后为每个订阅者选择第一条记录。这是一个例子

;WITH CTE AS
(
  SELECT P2P.SubscriberID , 
         P2P.AddresseeNumber,
         P.Name,
         P.LastName,
         DATEDIFF(minute, P2P.CallStart, P2P.CallEnd) AS TimeCall,
         ROW_NUMBER() OVER(PARTITION BY P2P.SubscriberID
                          ORDER BY DATEDIFF(minute, P2P.CallStart, P2P.CallEnd) DESC) AS RN 
  FROM dbo.NetworkP2P AS P2P
  JOIN Subscriber S
    ON P2P.SubscriberID = S.SubscriberID
  JOIN Person P
    ON S.PersonID = P.PersonID
  WHERE P2P.ServiceID IN(1,2)
)
SELECT SubscriberID , 
       AddresseeNumber,
       Name,
       LastName,
       TimeCall
FROM CTE
WHERE RN = 1
ORDER BY SubscriberID 

这会给你最长的订阅者通话时间

SELECT P2P.SubscriberID , P.Name, P.LastName, P2P.AddresseeNumber, DATEDIFF(minute, P2P.CallStart, P2P.CallEnd) as 'TimeCall'
FROM dbo.NetworkP2P AS P2P
JOIN dbo.Subscriber AS S ON P2P.SubscriberID=S.SubscriberID
JOIN dbo.Person AS P ON S.PersonID=P.PersonID
WHERE P2P.ServiceID IN(1,2) 
AND DATEDIFF(minute, P2P.CallStart, P2P.CallEnd)=(SELECT max(DATEDIFF(minute, P2P2.CallStart, P2P2.CallEnd)) 
    FROM dbo.NetworkP2P AS P2P2)
GROUP BY p2p.SubscriberID
ORDER BY P2P.SubscriberID ASC

这将为您提供匹配最长通话时长的所有订阅者中最长的通话。

SELECT P2P.SubscriberID , P.Name, P.LastName, P2P.AddresseeNumber, DATEDIFF(minute, CallStart, CallEnd) as 'TimeCall'
FROM dbo.NetworkP2P AS P2P
JOIN dbo.Subscriber AS S ON P2P.SubscriberID=S.SubscriberID
JOIN dbo.Person AS P ON S.PersonID=P.PersonID
WHERE P2P.ServiceID IN(1,2) 
AND DATEDIFF(minute, P2P.CallStart, P2P.CallEnd)=(SELECT max(DATEDIFF(minute, P2P2.CallStart, P2P2.CallEnd)) 
    FROM dbo.NetworkP2P AS P2P2)

如果你想保证只得到一条记录,加LIMIT,如果超过1条相同长度,你将得到第一条最长的记录

SELECT P2P.SubscriberID , P.Name, P.LastName, P2P.AddresseeNumber, DATEDIFF(minute, CallStart, CallEnd) as 'TimeCall'
FROM dbo.NetworkP2P AS P2P
JOIN dbo.Subscriber AS S ON P2P.SubscriberID=S.SubscriberID
JOIN dbo.Person AS P ON S.PersonID=P.PersonID
WHERE P2P.ServiceID IN(1,2) 
AND DATEDIFF(minute, P2P.CallStart, P2P.CallEnd)=(SELECT max(DATEDIFF(minute, P2P2.CallStart, P2P2.CallEnd)) 
    FROM dbo.NetworkP2P AS P2P2)
LIMIT 1