【发布时间】:2021-07-21 03:16:09
【问题描述】:
假设我们有 2 个名为 Records 和 Opportunities 的表:
记录:
| RecordID | CustomerID | CreateDate |
|---|---|---|
| 777 | 1 | 1/1/2021 |
| 888 | 2 | 1/1/2021 |
| 999 | 1 | 2/1/2021 |
机会:
| OppID | CustomerID | OppCreateDate |
|---|---|---|
| 10 | 1 | 12/31/2020 |
| 11 | 1 | 1/10/2021 |
| 12 | 2 | 2/1/2021 |
| 13 | 1 | 4/1/2021 |
| 14 | 1 | 8/5/2025 |
期望的输出:
| RecordID | CustomerID | CreateDate | #Opportunities |
|---|---|---|---|
| 777 | 1 | 1/1/2021 | 1 |
| 888 | 2 | 1/1/2021 | 1 |
| 999 | 1 | 2/1/2021 | 1 |
如您所见,Records 表提供了所需输出的前 3 列,而“#Opportunities”列是通过计算在创建记录之后发生的机会数创建的对于给定的客户。
关于这个逻辑需要注意两点:
- 仅计算在记录后 6 个月内发生的机会。
- 如果为客户创建了另一条记录,则只计算最近记录的机会。
更具体地说,OppID = 11 将记入 RecordID = 777; 12 至 888;和 13 到 999。10 和 14 不会记入任一 RecordID。
我写了下面的代码,没有考虑到上面的#2:
CREATE TABLE #Records
(
RecordID int
, CustomerID int
, CreateDate Date
)
INSERT INTO #Records
VALUES
(777, 1, '2021-01-01')
, (888, 2, '2021-01-31')
, (999, 1, '2021-02-01')
CREATE TABLE #Opportunities
(
OppID int
, CustomerID int
, OppCreateDate Date
)
INSERT INTO #Opportunities
VALUES
(10, 1, '2020-12-31')
, (11, 1, '2021-01-10')
, (12, 2, '2021-02-01')
, (13, 1, '2021-04-01')
, (14, 1, '2025-08-25')
select *
from #Records
select *
from #Opportunities
select rec.*
, (select count(*)
from #Opportunities opp
where rec.CustomerID=opp.CustomerID
and rec.CreateDate<=opp.OppCreateDate --record happened on the same day or before the opportunity
and datediff(month,rec.CreateDate,opp.OppCreateDate) < 6 --opened and created within 6 months
) as [#Opportunities]
from #Records rec
有什么建议可以合并上面的 #2 并生成所需的输出?
【问题讨论】:
-
RecordID 是否会阻止您为该客户获得正确的机会计数?
-
好吧,这样做看起来很难,因为记录和机会之间似乎没有关系——只有客户和机会。你的计数永远是一,对吗?
-
所以让我直截了当地说 - (RecordID,CustomerID) 是否有主键定义?因为从表面上看,您所说的要么是糟糕的数据结构设计,要么是您遗漏了我们需要的细节。
-
当你提到糟糕的数据结构时,我笑了。我必须破解这个坚果的原因是因为这个事实!让我试着这样解释:可以为客户创建许多记录;可以为客户创造很多机会;创造机会并不总是需要记录;创建机会时,我想将其归因于最接近该机会创建日期的记录(只要它在 [记录] 创建日期的 6 个月内。这有帮助吗?
-
是的,哎呀,真疼,哈哈
标签: sql sql-server date join duplicates