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 |
谁能建议我的脚本应该如何修改以获得正确的计数?
答案 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