查找谁给谁打电话
Finding who called who
我有这两个 table。订阅者 table 包含订阅者 ID 和他的 Phone 号码。 NetworkP2P 内容 SubscriberID、他呼叫的对象 AddresseeNumber 以及呼叫开始、结束的时间。
TABLE Subscriber
(
SubscriberID int,
PhoneNumber char(10)
)
TABLE NetworkP2P
(
SubscriberID int,
AddresseeNumber char(10),
CallStart datetime,
CallEnd datetime
)
示例数据:
订阅者
SubscriberID | PhoneNumber
1 613-555-0156
2 613-555-0112
3 613-555-0119
4 613-555-0182
网络P2P
SubscriberID | AddresseeNumber | CallStart | CallEnd
1 613-555-0182 2013-02-03 08:27:00.000 2013-02-03 08:30:54.000
1 613-555-0119 2013-02-03 10:11:26.000 2013-02-03 10:14:26.000
1 613-555-3333 2013-02-03 15:13:58.000 2013-02-03 15:18:13.000
2 613-555-0156 2013-02-05 23:21:50.000 2013-02-05 23:24:50.000
2 613-555-0119 2013-04-05 23:21:50.000 2013-04-05 23:26:50.000
3 613-555-0112 2013-06-05 23:21:50.000 2013-06-05 23:26:50.000
并非所有 Phone 号码都与订阅者拥有的号码匹配。
如果我希望输出在给定月份内相互联系的订阅者(即订阅者 1 调用订阅者 2,反之亦然),我将如何处理?
所需输出示例:
Caller | Reciever | CallerPhone | RecieverPhone
1 4 613-555-0156 613-555-0182
1 3 613-555-0156 613-555-0119
2 1 613-555-0112 613-555-0156
2 3 613-555-0112 613-555-0119
3 2 613-555-0119 613-555-0112
您的模型并没有像评论中建议的那样错误 - 您的 NetworkP2P 可能只缺少一列(Reciever),它可以作为可选的外键(以满足您的句子“并非所有 Phone 数字都匹配订阅者拥有的那些。”),但它看起来比关系更日志 table。
查询您想要的输出:
select
caller.SubscriberID as Caller,
reciever.SubscriberID as Reciever,
caller.PhoneNumber as CallerPhone,
nt.AddresseeNumber as RecieverPhone, -- better than reciever.PhoneNumber because you can use left join recievers to get missing substribers
nt.CallStart,
nt.CallEnd
from Subscriber as caller
inner join NetworkP2P as nt
on nt.SubscriberID = caller.SubscriberID
inner join Subscriber as reciever
on nt.AddresseeNumber = reciever.PhoneNumber
-- where '2021-02-03' between nt.CallStart and nt.CallEnd -- calls in 2021-02-03
-- where nt.CallStart between '2021-02-01' and '2021-02-28' -- calls in specific interval
-- where eomonth(nt.CallStart) = eomonth('2021-02-01') -- calls in specific month
您应该始终为所有 table 使用数据库架构(例如 dbo.Subscriber)。
订阅者的两个连接应该可以做到。
SELECT
nw.SubscriberID AS Caller
, rcvr.SubscriberID AS Receiver
, callr.PhoneNumber AS CallerPhone
, nw.AddresseeNumber AS ReceiverPhone
FROM NetworkP2P nw
JOIN Subscriber callr ON callr.SubscriberID = nw.SubscriberID
LEFT JOIN Subscriber rcvr ON rcvr.PhoneNumber = nw.AddresseeNumber
WHERE rcvr.SubscriberID IS NOT NULL
ORDER BY Caller, Receiver
Caller
Receiver
CallerPhone
ReceiverPhone
1
3
613-555-0156
613-555-0119
1
4
613-555-0156
613-555-0182
2
1
613-555-0112
613-555-0156
2
3
613-555-0112
613-555-0119
3
2
613-555-0119
613-555-0112
演示 db<>fiddle here
我有这两个 table。订阅者 table 包含订阅者 ID 和他的 Phone 号码。 NetworkP2P 内容 SubscriberID、他呼叫的对象 AddresseeNumber 以及呼叫开始、结束的时间。
TABLE Subscriber
(
SubscriberID int,
PhoneNumber char(10)
)
TABLE NetworkP2P
(
SubscriberID int,
AddresseeNumber char(10),
CallStart datetime,
CallEnd datetime
)
示例数据:
订阅者
SubscriberID | PhoneNumber
1 613-555-0156
2 613-555-0112
3 613-555-0119
4 613-555-0182
网络P2P
SubscriberID | AddresseeNumber | CallStart | CallEnd
1 613-555-0182 2013-02-03 08:27:00.000 2013-02-03 08:30:54.000
1 613-555-0119 2013-02-03 10:11:26.000 2013-02-03 10:14:26.000
1 613-555-3333 2013-02-03 15:13:58.000 2013-02-03 15:18:13.000
2 613-555-0156 2013-02-05 23:21:50.000 2013-02-05 23:24:50.000
2 613-555-0119 2013-04-05 23:21:50.000 2013-04-05 23:26:50.000
3 613-555-0112 2013-06-05 23:21:50.000 2013-06-05 23:26:50.000
并非所有 Phone 号码都与订阅者拥有的号码匹配。
如果我希望输出在给定月份内相互联系的订阅者(即订阅者 1 调用订阅者 2,反之亦然),我将如何处理?
所需输出示例:
Caller | Reciever | CallerPhone | RecieverPhone
1 4 613-555-0156 613-555-0182
1 3 613-555-0156 613-555-0119
2 1 613-555-0112 613-555-0156
2 3 613-555-0112 613-555-0119
3 2 613-555-0119 613-555-0112
您的模型并没有像评论中建议的那样错误 - 您的 NetworkP2P 可能只缺少一列(Reciever),它可以作为可选的外键(以满足您的句子“并非所有 Phone 数字都匹配订阅者拥有的那些。”),但它看起来比关系更日志 table。
查询您想要的输出:
select
caller.SubscriberID as Caller,
reciever.SubscriberID as Reciever,
caller.PhoneNumber as CallerPhone,
nt.AddresseeNumber as RecieverPhone, -- better than reciever.PhoneNumber because you can use left join recievers to get missing substribers
nt.CallStart,
nt.CallEnd
from Subscriber as caller
inner join NetworkP2P as nt
on nt.SubscriberID = caller.SubscriberID
inner join Subscriber as reciever
on nt.AddresseeNumber = reciever.PhoneNumber
-- where '2021-02-03' between nt.CallStart and nt.CallEnd -- calls in 2021-02-03
-- where nt.CallStart between '2021-02-01' and '2021-02-28' -- calls in specific interval
-- where eomonth(nt.CallStart) = eomonth('2021-02-01') -- calls in specific month
您应该始终为所有 table 使用数据库架构(例如 dbo.Subscriber)。
订阅者的两个连接应该可以做到。
SELECT nw.SubscriberID AS Caller , rcvr.SubscriberID AS Receiver , callr.PhoneNumber AS CallerPhone , nw.AddresseeNumber AS ReceiverPhone FROM NetworkP2P nw JOIN Subscriber callr ON callr.SubscriberID = nw.SubscriberID LEFT JOIN Subscriber rcvr ON rcvr.PhoneNumber = nw.AddresseeNumber WHERE rcvr.SubscriberID IS NOT NULL ORDER BY Caller, Receiver
Caller | Receiver | CallerPhone | ReceiverPhone |
---|---|---|---|
1 | 3 | 613-555-0156 | 613-555-0119 |
1 | 4 | 613-555-0156 | 613-555-0182 |
2 | 1 | 613-555-0112 | 613-555-0156 |
2 | 3 | 613-555-0112 | 613-555-0119 |
3 | 2 | 613-555-0119 | 613-555-0112 |
演示 db<>fiddle here