【问题标题】:T-SQL Finding person with most calls and to who he has called [duplicate]T-SQL查找电话最多的人以及他打电话给谁[重复]
【发布时间】:2022-01-24 15:26:49
【问题描述】:

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

所有事情都必须在一个查询中完成。

我不明白如何处理的部分是,我可以通过 SubscriberID 找到最长的呼叫,但我无法准确显示它是哪个电话号码,因为如果我执行 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

此查询将显示所有呼叫并按所有呼叫的最大值排序。我将如何首先将电话号码添加到已选择的电话号码中?此外,在那之后,如何通过姓名和姓氏指定订阅者 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

【问题讨论】:

  • “我无法显示具体是哪个电话号码” 这是否回答了您的问题Get top 1 row of each group
  • 不幸的是,我没有发现它对我的问题有什么帮助。
  • 提问时,您需要提供minimal reproducible example: (1) DDL 和样本数据填充,即 CREATE 表和 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上述#1 中的样本数据。 (4) 您的 SQL Server 版本 (SELECT @@version;)。全部在问题内,没有图片。

标签: sql sql-server tsql


【解决方案1】:

您可以使用 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 

【讨论】:

    【解决方案2】:

    这将使您获得订阅者最长的通话时间

    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
    

    【讨论】:

    • 谢谢,我在运行第一个时遇到问题,因为它需要我将所有 Select 语句添加到 GROUP BY,有什么办法可以克服吗?
    猜你喜欢
    • 2022-01-25
    • 2020-12-29
    • 2012-02-09
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 2015-07-22
    相关资源
    最近更新 更多