使用MIN() OVER PARTITION出现重复行,如何合并行实现行转列?
解决SQL行转列后重复行合并问题
你的问题出在使用窗口函数而非聚合函数,窗口函数会保留原表的所有行,仅在对应行计算出目标值,其他行留空;而要合并成单行,需要用聚合函数配合CASE语句,再通过GROUP BY分组聚合。
正确的SQL写法
SELECT consumer_id, product_id, MAX(CASE WHEN prod_state = 'wholesale' THEN date END) AS wholesale_date, MAX(CASE WHEN prod_state = 'stock' THEN date END) AS stock_date, MAX(CASE WHEN prod_state = 'sold' THEN date END) AS sold_date, MAX(CASE WHEN prod_state = 'return' THEN date END) AS return_date FROM your_table_name GROUP BY consumer_id, product_id;
逻辑说明
- CASE语句:针对每个
prod_state,仅在匹配的行返回对应的date,不匹配的行返回NULL - 聚合函数(MAX/MIN):同一
consumer_id+product_id组内,每个状态对应的date只有一个非NULL值,用MAX或MIN可直接提取该值,自动忽略NULL - GROUP BY:按
consumer_id和product_id分组,将同一用户同一产品的所有行聚合为一行
原写法失效原因
你使用的MIN(date) OVER(PARTITION BY ...)是窗口函数,它的作用是在指定分组内计算最小值,但不会减少原表的行数,所以原表4行的情况下,结果仍为4行,每行仅对应状态的列有值、其余为NULL。而聚合函数+GROUP BY会直接合并分组内的行,同时提取有效数据。
如果你的场景中同一consumer_id+product_id+prod_state存在多条记录,用MIN(date)或MAX(date)可分别取最早/最晚的日期,适配业务需求。
内容的提问来源于stack exchange,提问作者c_n_blue
相关产品推荐
相关产品推荐

