在一个查询中对同一表的多个左连接进行计数

时间:2021-01-27 15:41:57

标签: sql-server tsql

SQL 专家们,我有一个员工电话号码表和一个表,记录了一年多来我们组织打来的每个电话,需要为每个电话号码计算拨打和接听电话的数量。

表格电话号码

<头>
电话号码 用户名 电子邮件地址
02078821122 JBloggs jbloggs@myorg.com

调用

<头>
日期 调用源 呼叫目的地
12/10/2020 07805424828 02078821122

所以我的 T-SQL 脚本如下所示,因为我需要对 Calls 表进行两次左连接,因为员工电话号码可能是呼叫的来源或目的地:

SELECT P.PhoneNumber, count(CS.CallSource) AS CallsMade, count(CD.CallDestination) AS CallsReceived
FROM PhoneNumbers P
LEFT JOIN Calls CS ON P.PhoneNumber = CS.CallSource 
LEFT JOIN Calls CD ON P.PhoneNumber = CD.CallDestination 
GROUP BY P.PhoneNumber
ORDER BY PhoneNumber

我也需要零计数,因此是 LEFT JOIN。尽管脚本在运行,但 GROUP BY 会导致 CallsMade 总数乘以每个 PhoneNumber 的 CallsReceived 值,并将结果放在两列中。例如,假设 PhoneNumber 02078820011 打了 3 个电话,接了 2 个电话,上面的脚本正在返回:

<头>
电话号码 来电 已接来电
02078820011 6 6

什么时候应该:

<头>
电话号码 来电 已接来电
02078820011 3 2

谁能建议我的脚本应该如何修改以获得正确的计数?

2 个答案:

答案 0 :(得分:0)

取消调用并聚合:

SELECT v.PhoneNumber, SUM(source) as num_source,
       SUM(destination) as num_destination
FROM Calls c CROSS APPLY
     (VALUES (c.CallSource, 1, 0), (c.CallDestination, 0, 1)
     ) v(PhoneNumber, source, destination)
GROUP BY v.PhoneNumber
ORDER BY v.PhoneNumber;

如果您只关心 PhoneNumbers 列表中的数字,可以使用:

SELECT p.PhoneNumber, SUM(source) as num_source,
       SUM(destination) as num_destination
FROM PhoneNumbers p LEFT JOIN
     (Calls c CROSS APPLY
      (VALUES (c.CallSource, 1, 0), (c.CallDestination, 0, 1)
      ) v(PhoneNumber, source, destination)
     )
     ON p.PhoneNumber = v.PhoneNumber
GROUP BY p.PhoneNumber
ORDER BY p.PhoneNumber;

答案 1 :(得分:0)

只需使用一个 cross join 结合两个 case 测试:

select p.number, sum(case c.source when p.number then 1 else 0 end) sent, sum(case c.destination when p.number then 1 else 0 end) recieved
from phone p
cross join calls c
group by p.number