首页 > 解决方案 > 将按日期较早/较晚的最近相邻行返回到另一个表的日期

问题描述

问题:根据以下内容返回单个结果集

对于报告表 (rdate) 中的每个日期,将早于或等于 rdate(加上 t1 和 t2)的最新事务表 (tdate) 返回为 sdate,s1,s2

对于报告表 (rdate) 中的每个日期,将晚于或等于 rdate(加上 t1 和 t2)的最早事务表 (tdate) 返回为 edate,e1,e2

已尝试 TOP 1 / APPLY / LEAD& LAG 代码,但无法获得所需的结果。

任何建议表示赞赏。谢谢

报告表

日期
2021 年 6 月 1 日
26/01/2021
15/02/2021

交易表

日期 t1 t2
2021 年 1 月 1 日 17 6
2021 年 5 月 1 日 5 9
2021 年 9 月 1 日 8 12
19/01/2021 15 11
20/01/2021 12 8
25/01/2021 9 1
26/01/2021 8 17
2021 年 1 月 30 日 7 6
2021 年 8 月 2 日 6 21
22/02/2021 14 5
27/02/2021 11 4

需要结果

日期 日期 s1 s2 约会 e1 e2
2021 年 6 月 1 日 2021 年 5 月 1 日 5 9 2021 年 9 月 1 日 8 12
26/01/2021 26/01/2021 8 17 26/01/2021 8 17
15/02/2021 2021 年 8 月 2 日 6 21 22/02/2021 14 5

标签: sql-serversql-server-2019

解决方案


A CROSS APPLYor与适当OUTER APPLY的顺序和过滤条件一起使用SELECT TOP 1应该可以解决问题。尝试:

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

OUTER APPLY类似于,LEFT JOIN不允许CROSS APPLY找到任何记录。仔细查看不等式条件以确保边缘情况符合预期。


推荐阅读