如何在Redshift中对行内多日期列排序并获取date_x的前序日期?
在Redshift中获取每行恰好早于指定日期的列值及列名
要实现你提出的两个需求,核心是把宽表的多日期列转为长表结构,方便对每行的日期进行排序筛选,再聚合得到目标结果。以下是具体的SQL实现方案:
完整SQL代码
假设你的表名为your_table,执行以下语句即可得到期望结果:
WITH unpivoted_dates AS ( SELECT row, date_x, col_name, col_date FROM your_table UNPIVOT ( col_date FOR col_name IN (date_a, date_b, date_c, date_d) ) AS unpvt ), ranked_dates AS ( SELECT row, date_x, col_name, col_date, ROW_NUMBER() OVER (PARTITION BY row ORDER BY col_date DESC) AS rn FROM unpivoted_dates WHERE col_date < date_x ) SELECT t.*, rd.col_date AS date_before_x, rd.col_name AS status FROM your_table t LEFT JOIN ranked_dates rd ON t.row = rd.row AND rd.rn = 1 ORDER BY t.row;
代码逻辑说明
- unpivoted_dates 子查询:把原表中
date_a到date_d的列转成行记录,每一行对应一个日期列的名称(col_name)和日期值(col_date),同时保留原行号row和参考日期date_x。这一步解决了“按时间排序每行日期”的基础需求,转成行后排序更方便。 - ranked_dates 子查询:先过滤出所有早于
date_x的日期,再按row分组,对每个分组内的日期按降序排序,用ROW_NUMBER()给每条记录标记序号。序号为1的记录,就是该行中最接近date_x且早于它的日期。 - 最终关联查询:把原表和筛选后的结果关联,取序号为1的记录,补充
date_before_x(目标日期值)和status(对应的列名)两列,得到最终输出。
特殊情况处理
如果某一行中所有日期都不早于date_x,date_before_x和status会返回NULL。如果需要自定义这种情况的显示值,可以用COALESCE函数替换,比如:
COALESCE(rd.col_date, '无符合条件日期') AS date_before_x, COALESCE(rd.col_name, '无') AS status
内容的提问来源于stack exchange,提问作者nomnom3214
相关产品推荐
相关产品推荐

