提问人:snappymcsnap 提问时间:11/7/2023 更新时间:11/7/2023 访问量:47
如何在联接中仅使用满足条件的第一个值?
How do I use just the first value that satisfies a condition in my join?
问:
我试着思考最有效的方法是什么,希望你能提供帮助。我有两个表,一个是客户呼叫数据(客户呼叫客户服务号码),另一个是发票数据。它们来自不同的来源,因此没有共享的 PK-FK 关系。下面是一些示例数据:
呼叫数据
呼叫 ID | 电话号码 | 源 | 呼叫日期 |
---|---|---|---|
12345 | 555-555-5555 | 互联网 | 2023-11-06 |
12346 | 555-666-6666 | 转 介 | 2023-01-01 |
12347 | 555-666-6666 | 转 介 | 2023-02-02 |
12348 | 555-666-6666 | 互联网 | 2023-05-17 |
12349 | 555-777-7777 | 转 介 | 2023-10-31 |
12350 | 555-777-7777 | 互联网 | 2023-11-03 |
发票
发票 Id | 电话号码 | 量 | 发票日期 |
---|---|---|---|
11111 | 555-555-5555 | 250.56 | 2023-01-01 |
22222 | 555-666-6666 | 376.67 | 2023-02-01 |
33333 | 555-666-6666 | 761.09 | 2023-06-02 |
44444 | 555-666-6666 | 316.23 | 2023-07-03 |
55555 | 555-777-7777 | 145.33 | 2023-10-01 |
66666 | 555-777-7777 | 986.92 | 2023-11-01 |
我需要能够根据 PhoneNumber 将这两者连接在一起。但我只关心 CallData.Source = 'referral' 的记录,这样就消除了上面除了 3 个 CallData 记录之外的所有记录。然后,我想对所有 Invoice.Amount 值求和,但前提是 InvoiceDate 至少大于 CallDates 之一。
因此,请考虑电话号码为 555-666-6666 的 CallData 记录,有 2 个是引用类型,它们的 CallDates 为:
- 2023-01-01
- 2023-02-02
在 Invoice 表中,有 3 张发票的 InvoiceDates 为:
- 2023-02-01
- 2023-06-02
- 2023-07-03
我所关心的是,所有 3 个 InvoiceDates 都在至少一个匹配的 CallDates(在本例中为 2023-01-01)之后,所以我会将所有三个相加并得到 1453.99。
如果您有任何其他问题,请告诉我,谢谢
答:
-1赞
Luuk
11/7/2023
#1
您没有指定所需的输出,因此:
SELECT DISTINCT
CallId,
CallData.PhoneNumber,
SUM(Amount) OVER (Partition BY CallId,CallData.PhoneNumber) as "sum"
FROM CallData
INNER JOIN Invoice ON Invoice.PhoneNumber = CallData.PhoneNumber
AND Invoice.InvoiceDate > CallData.CallDate
WHERE CallData.Source = 'referral'
;
输出:
呼叫 ID | 电话号码 | 和 |
---|---|---|
12346 | 555-666-6666 | 1454 |
12347 | 555-666-6666 | 1077 |
12349 | 555-777-7777 | 987 |
请参见:DBFIDDLE
此 SQL 语句的 90% 是您在问题中写的内容到 SQL 语法的字面翻译。
或者,仅通过电话号码:
SELECT DISTINCT
CallData.PhoneNumber,
SUM(Amount) OVER (Partition BY CallData.PhoneNumber) as "sum"
FROM CallData
INNER JOIN Invoice ON Invoice.PhoneNumber = CallData.PhoneNumber
AND Invoice.InvoiceDate > CallData.CallDate
WHERE CallData.Source = 'referral'
;
请参见:DBFIDDLE
评论
0赞
snappymcsnap
11/7/2023
对不起,应该在输出上更清楚,这很接近,但它不应该按 CallId 求和,而应该按 PhoneNumber 求和......所以 555-666-6666 = 1454 和 55-777-7777 = 987
0赞
Luuk
11/7/2023
查看电话号码,因此 555-666-6666 的总和将是 2531
1赞
user1191247
11/7/2023
#2
您可以使用 MIN() 来获取每个 PhoneNumber 的最小 CallDate:
SELECT Calls.*, SUM(Invoice.Amount) AS Amount
FROM (
SELECT PhoneNumber, MIN(CallDate) AS MinCallDate
FROM CallData
WHERE Source = 'referral'
GROUP BY PhoneNumber
) Calls
JOIN Invoice
ON Invoice.PhoneNumber = Calls.PhoneNumber
AND Invoice.InvoiceDate >= Calls.MinCallDate
GROUP BY Calls.PhoneNumber;
输出:
电话号码 | MinCallDate | 量 |
---|---|---|
555-666-6666 | 2023-01-01 | 1453.99 |
555-777-7777 | 2023-10-31 | 986.92 |
这是一个 db<>小提琴。
评论