MySQL行转列:按产品ID将唯一日期转为列,最多显示2个日期
解决方案
要实现你需要的需求,我们可以通过去重+窗口函数+条件聚合的组合来完成,具体的MySQL查询语句如下:
SELECT ROW_NUMBER() OVER (ORDER BY product_id) AS id, product_id, MAX(CASE WHEN rn = 1 THEN date END) AS date1, MAX(CASE WHEN rn = 2 THEN date END) AS date2 FROM ( -- 给每个product_id的唯一日期分配行号 SELECT product_id, date, ROW_NUMBER() OVER (PARTITION BY product_id ORDER BY date) AS rn FROM ( -- 先去除同一product_id下的重复日期 SELECT DISTINCT product_id, date FROM your_table ) AS unique_dates ) AS ranked_dates -- 只保留每个product_id的前2个日期 WHERE rn <= 2 GROUP BY product_id ORDER BY product_id;
语句逻辑拆解
我们一步步梳理这个查询的工作流程:
内层子查询
unique_dates:
使用SELECT DISTINCT过滤掉同一product_id下的重复日期,确保每个日期只被统计一次,避免后续处理出现冗余数据。中间层子查询
ranked_dates:
借助窗口函数ROW_NUMBER(),以product_id为分组依据,对每个分组内的日期升序排序后分配行号。这样每个product_id的最早日期会被标记为rn=1,第二早的标记为rn=2,多余的日期会被标记为更大的行号。外层聚合查询:
- 用
CASE WHEN配合MAX()做条件聚合,把行号为1的日期映射到date1字段,行号为2的映射到date2字段; - 用
ROW_NUMBER() OVER (ORDER BY product_id)生成新的自增id,匹配你期望的输出格式; - 最后通过
GROUP BY product_id分组,保证每个product_id只输出一行结果。
- 用
可选调整
如果你想保留每个product_id的最晚两个日期,只需要把中间层的ORDER BY date改成ORDER BY date DESC即可。
内容的提问来源于stack exchange,提问作者Arun Roy
相关产品推荐
相关产品推荐

