如何实现SQL中基于±2天日期范围的表数据匹配查询?
问题:筛选Table A中不在Table B对应日期±2天范围内且匹配其他字段的数据
数据结构与示例数据
Table A 原始数据
col_1, col_2, col_3, col4 04/04/2017 1800.00 200.00 B123 21/04/2017 1800.00 200.00 B123 14/09/2017 1200.00 300.00 B123 18/12/2017 1100.00 150.00 B123 21/01/2018 1100.00 150.00 B123 06/05/2017 2400.00 500.00 A345
Table A 新增测试数据
05/04/2017 1800.00 200.00 B123 05/04/2017 1800.00 200.00 B123 06/04/2017 1800.00 200.00 B123
Table B 数据
col_1, col_2, col_3, col4 05/04/2017 1800.00, 200.00 B123 12/09/2017 1200.00, 300.00 B123 20/12/2017 1100.00, 150.00 B123 08/05/2017 2400.00 500.00 A345
需求描述
希望筛选出Table A中不存在于Table B对应col_1±2天范围内、且col_2、col_3、col4完全匹配的数据,伪代码逻辑如下:
select * from A where (col_1, col_2, col_3, col_4) not in (select +/- 2 days_of_col_1, col_2, col_3, col_4 from B)
此前尝试过窗口函数,但只能检测同一日期的重复条目,无法满足日期范围匹配的需求。
解决方案
当然可以实现这个需求!核心思路是用NOT EXISTS子查询关联两张表,精准检查Table B中是否存在符合条件的记录——也就是和Table A当前行的col_2、col_3、col4完全匹配,且日期在A行日期的±2天范围内。
通用SQL模板(适配主流数据库)
SELECT a.* FROM TableA a WHERE NOT EXISTS ( SELECT 1 FROM TableB b WHERE b.col_2 = a.col_2 AND b.col_3 = a.col_3 AND b.col4 = a.col4 -- 核心:日期范围判断,根据数据库类型调整日期函数 AND b.col_1 BETWEEN DATE_SUB(a.col_1, INTERVAL 2 DAY) AND DATE_ADD(a.col_1, INTERVAL 2 DAY) );
不同数据库的日期函数调整
不同数据库对日期运算的语法略有差异,这里给出几个常用数据库的适配写法:
- MySQL/MariaDB:直接使用模板中的
DATE_SUB和DATE_ADD - PostgreSQL:用区间运算简化写法
AND b.col_1 BETWEEN a.col_1 - INTERVAL '2 days' AND a.col_1 + INTERVAL '2 days' - Oracle:假设
col_1是DATE类型,直接加减天数AND b.col_1 BETWEEN a.col_1 - 2 AND a.col_1 + 2 - SQL Server:使用
DATEADD函数AND b.col_1 BETWEEN DATEADD(DAY, -2, a.col_1) AND DATEADD(DAY, 2, a.col_1)
逻辑解释
- 遍历Table A的每一行数据,子查询会去Table B中查找三个条件同时满足的记录:
col_2、col_3、col4与A行完全匹配- B行日期落在A行日期的前2天到后2天区间内(包含边界日期)
- 如果子查询找不到任何符合条件的记录,说明A行满足需求,会被保留在结果集中;反之则被排除。
针对补充测试数据的验证
你新增的三条Table A数据,日期分别是05/04/2017和06/04/2017,都落在Table B中05/04/2017记录的±2天范围内(03/04-07/04),且其他字段完全匹配,所以子查询会找到对应的B行,这三条数据会被排除,完全符合你的预期。
内容的提问来源于stack exchange,提问作者Shh
相关产品推荐
相关产品推荐

