当出现多个日期但受频率计数限制时,使用单一日期的SQL联接



在SQL中,我希望将一个表中有多个日期的两个表连接到另一个表的一个日期,我希望受一个表频率的限制。相反,我不断地得到所有频率的所有记录的总和。

我尝试过联接,where子句和子查询,但一直出错。我最近被引导到Dibble,觉得这是演示问题的最佳方式:

https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=a9fec08a4ec5130c93da6ed663259da4

示例表格有:

CREATE TABLE dbo.Action
(
ActionWeek date, 
ActionYear int,
Region nvarchar(50), 
Action nvarchar(50), 
ActionAmount int, 
Frequency int);
INSERT INTO Action values
('2019-01-01' , 2019, 'Wales', 'abc123', 123, 1),
('2019-03-10' , 2019, 'Wales', 'abc123', 132, 2),
('2019-06-01' , 2019, 'Wales', 'abc123', 153, 3),
('2020-01-11' , 2020, 'Wales', 'abc123', 123, 1),
('2019-01-01' , 2019, 'Australia', 'abd133', 723, 1),
('2019-08-01' , 2019, 'Australia', 'abd133', 763, 2),
('2020-04-01' , 2020, 'Australia', 'abd133', 823, 1),
('2019-01-01' , 2019, 'Mexico', 'cbc423', 3123, 1),
('2020-03-01' , 2020, 'Mexico', 'cbc423', 3223, 1),
('2020-05-01' , 2020, 'Mexico', 'cbc423', 3423, 2),
('2020-08-21' , 2020, 'Mexico', 'cbc423', 3623, 3),
('2021-01-01' , 2021, 'Mexico', 'cbc423', 3723, 1),
('2021-09-01' , 2021, 'Mexico', 'cbc423', 3823, 2)
-- Second Table
CREATE TABLE dbo.Response
(
ResponseYear int,
ResponseAction nvarchar(50),
ResponseDate date, 
ResponseWeek date, 
ResponseValue float,
);

INSERT INTO Response values
(2019, 'abc123', '2019-02-04', '2019-02-01', 50),
(2019, 'abc123', '2019-02-08', '2019-02-08', 25),
(2019, 'abc123', '2019-09-24', '2019-09-24', 100),
(2020, 'abc123', '2020-01-20', '2019-01-23', 5),
(2021, 'abc123', '2021-06-10', '2021-06-07', 3),
(2019, 'abd133', '2019-01-10', '2019-01-07', 15),
(2019, 'abd133', '2019-02-10', '2019-02-04', 25),
(2019, 'abd133', '2019-03-10', '2019-03-04', 35),
(2021, 'cbc423', '2021-01-13', '2021-01-11', 77)

期望的结果是:

A.ActionWeek / A.Action / A.Frequency / R.ResponseValue
2019-01-01 / abc123 / 1 / 75
2019-03-10 / abc123 / 2 / 0
2019-06-01 / abc123 / 3 / 100
2020-01-11 / abc123 / 1 / 8
2019-01-01 / abd133 / 1 / 75
2019-08-01 / abd133 / 2 / 0
2020-04-01 / abd133 / 1 / 0
2019-01-01 / cbc423 / 1 / 0
2020-03-01 / cbc423 / 1 / 0
2020-05-01 / cbc423 / 2 / 0
2020-08-21 / cbc423 / 3 / 0
2021-01-01 / cbc423 / 1 / 77
2021-09-01 / cbc423 / 2 / 0

如果你还有其他问题,请告诉我?

我试过这个:

SELECT  A.ActionWeek, A.Action, A.Frequency
, (SELECT SUM(R.ResponseValue)
FROM Response R2
JOIN Action A2 ON R2.Action and A2.Action
WHERE A.Frequency = A2.Frequency
) AS ResponseValue
FROM Action A
JOIN Response R ON A.Action = R.ResponseAction 
GROUP BY A.ActionWeek, A.Action, A.Frequency
ORDER BY A.ActionWeek, A.Action, A.Frequency

我完全不知道频率与此有关,而且您似乎不需要它,因为获取下一个日期用作加入测试很简单

with cte as
(select a.actionweek fromweek,a.action,a.frequency,
lead(a.actionweek) over (partition by a.action order by a.actionweek) toweek
from  [action] a)
select cte.fromweek,cte.toweek, cte.action,cte.frequency,r.responseweek,r.responsevalue
--sum(r.responsevalue) 
from cte
left join response r on cte.action = r.ResponseAction and  ResponseWeek between cte.fromweek and cte.toweek;

中的结果

fromweek   toweek     action                                             frequency   responseweek responsevalue
---------- ---------- -------------------------------------------------- ----------- ------------ ----------------------
2019-01-01 2019-03-10 abc123                                             1           2019-02-01   50
2019-01-01 2019-03-10 abc123                                             1           2019-02-08   25
2019-01-01 2019-03-10 abc123                                             1           2019-01-23   5
2019-03-10 2019-06-01 abc123                                             2           NULL         NULL
2019-06-01 2020-01-11 abc123                                             3           2019-09-24   100
2020-01-11 NULL       abc123                                             1           NULL         NULL
2019-01-01 2019-08-01 abd133                                             1           2019-01-07   15
2019-01-01 2019-08-01 abd133                                             1           2019-02-04   25
2019-01-01 2019-08-01 abd133                                             1           2019-03-04   35
2019-08-01 2020-04-01 abd133                                             2           NULL         NULL
2020-04-01 NULL       abd133                                             1           NULL         NULL
2019-01-01 2020-03-01 cbc423                                             1           NULL         NULL
2020-03-01 2020-05-01 cbc423                                             1           NULL         NULL
2020-05-01 2020-08-21 cbc423                                             2           NULL         NULL
2020-08-21 2021-01-01 cbc423                                             3           NULL         NULL
2021-01-01 2021-09-01 cbc423                                             1           2021-01-11   77
2021-09-01 NULL       cbc423                                             2           NULL         NULL
(17 row(s) affected)

将其更改为总和

with cte as
(select a.actionweek fromweek,a.action,a.frequency,
lead(a.actionweek) over (partition by a.action order by a.actionweek) toweek
from  [action] a)
select cte.fromweek,cte.action,cte.frequency,
sum(r.responsevalue) 
from cte
left join response r on cte.action = r.ResponseAction and  ResponseWeek between cte.fromweek and cte.toweek
group by cte.action,cte.fromweek,cte.frequency
order by cte.action,cte.fromweek,cte.frequency
fromweek   action                                             frequency   
---------- -------------------------------------------------- ----------- ----------------------
2019-01-01 abc123                                             1           80
2019-03-10 abc123                                             2           NULL
2019-06-01 abc123                                             3           100
2020-01-11 abc123                                             1           NULL
2019-01-01 abd133                                             1           75
2019-08-01 abd133                                             2           NULL
2020-04-01 abd133                                             1           NULL
2019-01-01 cbc423                                             1           NULL
2020-03-01 cbc423                                             1           NULL
2020-05-01 cbc423                                             2           NULL
2020-08-21 cbc423                                             3           NULL
2021-01-01 cbc423                                             1           77
2021-09-01 cbc423                                             2           NULL
Warning: Null value is eliminated by an aggregate or other SET operation.
(13 row(s) affected)