Problem: to return a single result set based on the following
for each date in report table (rdate) return the latest transaction table (tdate) that is earlier or equal to rdate (plus t1 & t2) as sdate,s1,s2
for each date in report table (rdate) return the earliest transaction table (tdate) that is later or equal to rdate (plus t1 & t2) as edate,e1,e2
Have attempted TOP 1 / APPLY / LEAD& LAG code, but cannot get results as required.
Any advice is appreciated. Thanks
Report table
rdate |
---|
06/01/2021 |
26/01/2021 |
15/02/2021 |
Transaction table
tdate | t1 | t2 |
---|---|---|
01/01/2021 | 17 | 6 |
05/01/2021 | 5 | 9 |
09/01/2021 | 8 | 12 |
19/01/2021 | 15 | 11 |
20/01/2021 | 12 | 8 |
25/01/2021 | 9 | 1 |
26/01/2021 | 8 | 17 |
30/01/2021 | 7 | 6 |
08/02/2021 | 6 | 21 |
22/02/2021 | 14 | 5 |
27/02/2021 | 11 | 4 |
Result required
rdate | sdate | s1 | s2 | edate | e1 | e2 |
---|---|---|---|---|---|---|
06/01/2021 | 05/01/2021 | 5 | 9 | 09/01/2021 | 8 | 12 |
26/01/2021 | 26/01/2021 | 8 | 17 | 26/01/2021 | 8 | 17 |
15/02/2021 | 08/02/2021 | 6 | 21 | 22/02/2021 | 14 | 5 |
CodePudding user response:
A CROSS APPLY
or OUTER APPLY
together with a SELECT TOP 1
with appropriate order and filter criteria should do the trick. Try:
DECLARE @ReportTable TABLE (rdate DATETIME)
INSERT @ReportTable
VALUES
('2021-01-06'),
('2021-01-26'),
('2021-02-15')
DECLARE @TransactionTable TABLE (tdate DATETIME, t1 INT, t2 INT)
INSERT @TransactionTable
VALUES
('2021-01-01', 17, 6),
('2021-01-05', 5, 9),
('2021-01-09', 8, 12),
('2021-01-19', 15, 11),
('2021-01-20', 12, 8),
('2021-01-25', 9, 1),
('2021-01-26', 8, 17),
('2021-01-30', 7, 6),
('2021-02-08', 6, 21),
('2021-02-22', 14, 5),
('2021-02-27', 11, 4)
SELECT * -- TODO: Assign meaningful names here
FROM @ReportTable R
OUTER APPLY (
SELECT TOP 1 *
FROM @TransactionTable T1
WHERE T1.tdate <= R.rdate
ORDER BY T1.tdate DESC
) S
OUTER APPLY (
SELECT TOP 1 *
FROM @TransactionTable T2
WHERE T2.tdate >= R.rdate
ORDER BY T2.tdate
) E
ORDER BY R.rdate
The OUTER APPLY
is like the LEFT JOIN
equivalent of CROSS APPLY
, allowing for no record found. Take a close look at the inequality conditions to ensure that the edge cases are as intended.