Oracle SQL多表关联后如何获取目标记录的前一行数据求助
嘿,这个需求其实用SQL的窗口函数就能轻松搞定!先看看你的数据集:
CARRCD FLTNBR IND DEPDATETIME ---- -------- ----- -------- AB 123 0 2020-10-29T14:00:00 AB 124 0 2020-10-29T10:00:00 AB 119 0 2020-10-29T09:00:00 AB 100 0 2020-10-29T08:00:00 AB 105 1 2020-10-29T07:00:00 ---------> Match AB 99 1 2020-10-29T06:00:00 AB 135 1 2020-10-29T04:00:00 AB 178 1 2020-10-29T02:00:00
从数据来看,你是按DEPDATETIME降序排列的,要找第一条IND=1记录的前一行,核心思路是先给每行标记顺序,再定位目标行的前一行。我给你几种通用的实现方式:
方法一:用行号定位(适配大部分数据库)
先通过CTE给每行按DEPDATETIME降序分配行号,然后找到第一个IND=1的行号,最后取行号减1的记录:
WITH ranked_data AS ( SELECT CARRCD, FLTNBR, IND, DEPDATETIME, ROW_NUMBER() OVER (ORDER BY DEPDATETIME DESC) AS row_num FROM your_table -- 替换成你的实际表名 ), first_ind1 AS ( SELECT row_num FROM ranked_data WHERE IND = 1 ORDER BY row_num LIMIT 1 -- MySQL/PostgreSQL用这个;SQL Server换成TOP 1;Oracle换成FETCH FIRST 1 ROW ONLY ) SELECT r.* FROM ranked_data r JOIN first_ind1 f ON r.row_num = f.row_num - 1;
方法二:用LAG窗口函数直接获取前一行数据
这种方法更直观,用LAG函数提前获取每行的前一行数据,然后过滤出第一个IND=1的记录,它的前一行数据就是我们要的结果:
WITH data_with_prev AS ( SELECT CARRCD, FLTNBR, IND, DEPDATETIME, -- 获取前一行的所有字段 LAG(CARRCD) OVER (ORDER BY DEPDATETIME DESC) AS prev_CARRCD, LAG(FLTNBR) OVER (ORDER BY DEPDATETIME DESC) AS prev_FLTNBR, LAG(IND) OVER (ORDER BY DEPDATETIME DESC) AS prev_IND, LAG(DEPDATETIME) OVER (ORDER BY DEPDATETIME DESC) AS prev_DEPDATETIME, ROW_NUMBER() OVER (ORDER BY DEPDATETIME DESC) AS row_num FROM your_table -- 替换成你的实际表名 ) SELECT prev_CARRCD AS CARRCD, prev_FLTNBR AS FLTNBR, prev_IND AS IND, prev_DEPDATETIME AS DEPDATETIME FROM data_with_prev WHERE IND = 1 ORDER BY row_num LIMIT 1; -- 同样根据数据库调整限制行数的语法
边界情况提醒
如果你的数据集第一条记录就是IND=1,那前一行不存在,这时候上面的查询会返回空结果。你可以根据需求加个判断,比如用IFNULL或者COALESCE处理,或者提前检查这种情况。
内容的提问来源于stack exchange,提问作者dvlpr
相关产品推荐
相关产品推荐

