Oracle SQL查询table1请求日期对应table2中最近下一个收货日期
Oracle SQL 匹配请求日期后最近收货日期实现方案
核心需求:按PO号关联两张表,取出table2中大于等于对应PO请求日期的最早一条收货日期,即请求当日或之后距离请求时间最近的收货记录。
方案1:OUTER APPLY 写法(Oracle 12c及以上版本推荐)
逻辑最直观,逐行遍历table1的记录,匹配table2中符合日期要求的记录,按收货日期升序取第一条即可,无匹配记录时保留table1原行,对应收货日期返回空值。
SELECT t1.PO, t1.RequestedDate, t2.ReceivedDate AS NearestReceivedDate FROM Table1 t1 OUTER APPLY ( SELECT ReceivedDate FROM Table2 t2 WHERE t2.PO = t1.PO AND t2.ReceivedDate >= t1.RequestedDate ORDER BY t2.ReceivedDate ASC FETCH FIRST 1 ROW ONLY ) t2
方案2:窗口函数写法(兼容11g及更早版本)
低版本Oracle不支持FETCH FIRST语法时,可以用ROW_NUMBER()窗口函数对关联后的符合条件的记录按收货日期排序,再取排序后序号为1的记录即可。
WITH match_rst AS ( SELECT t1.PO, t1.RequestedDate, t2.ReceivedDate, ROW_NUMBER() OVER( PARTITION BY t1.PO ORDER BY t2.ReceivedDate ASC ) AS rn FROM Table1 t1 LEFT JOIN Table2 t2 ON t1.PO = t2.PO AND t2.ReceivedDate >= t1.RequestedDate ) SELECT PO, RequestedDate, ReceivedDate AS NearestReceivedDate FROM match_rst WHERE rn = 1
运行结果验证
基于提供的样例数据,上述两种SQL返回结果完全匹配预期:
| PO | RequestedDate | NearestReceivedDate |
|---|---|---|
| 14888 | 01/12/2018 | 01/14/2018 |
| 14733 | 02/12/2018 | 02/12/2018 |
| 14555 | 05/12/2018 | 07/23/2018 |
注意事项
- 关联前请确认
RequestedDate和ReceivedDate均为DATE类型,若为字符串类型需先按对应格式转成日期,否则排序、大小对比会出现逻辑错误 - 若同一PO存在多条相同收货日期的符合条件记录,两种写法均能正常返回正确日期值,不会触发重复行报错
- 若某PO在table2中无满足“收货日期>=请求日期”的记录,返回结果中该PO对应的
NearestReceivedDate为NULL,不会丢失table1中的原始PO记录
内容的提问来源于stack exchange,提问作者Gbert2728
相关产品推荐
相关产品推荐

