如何通过group_by将同一客户的多行数据合并为单行?
解决方案
这里可以用窗口函数+条件聚合或者自连接两种方式实现,以下是具体SQL示例:
方法1:条件聚合(推荐,更简洁)
先给每个客户的记录按日期排序并编号,再通过聚合函数提取第一条和第二条记录的字段:
SELECT customer_id, MAX(CASE WHEN rn = 1 THEN date_hour END) AS date_hour, MAX(CASE WHEN rn = 1 THEN nature_transfer END) AS nature_transfer, MAX(CASE WHEN rn = 2 THEN date_hour END) AS date_hour_2, MAX(CASE WHEN rn = 2 THEN nature_transfer END) AS nature_transfer_2 FROM ( SELECT customer_id, date_hour, nature_transfer, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY date_hour) AS rn FROM your_table_name ) t GROUP BY customer_id;
说明:
ROW_NUMBER()按customer_id分组,给每组内的记录按date_hour升序编号(第一条记录为1,第二条为2)- 外层通过
CASE配合聚合函数MAX,分别提取每组内编号1和2的字段值,没有第二条记录时自动返回NULL
如果需要把nature_transfer转成对应文本(1→arrival,3→departure),可以把CASE里的nature_transfer替换成:
CASE nature_transfer WHEN 1 THEN 'arrival' WHEN 3 THEN 'departure' END
方法2:自连接
先给记录编号,再将第一条和第二条记录通过customer_id关联:
WITH numbered_records AS ( SELECT customer_id, date_hour, nature_transfer, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY date_hour) AS rn FROM your_table_name ) SELECT a.customer_id, a.date_hour, a.nature_transfer, b.date_hour AS date_hour_2, b.nature_transfer AS nature_transfer_2 FROM numbered_records a LEFT JOIN numbered_records b ON a.customer_id = b.customer_id AND a.rn = 1 AND b.rn = 2 WHERE a.rn = 1;
说明:
- 用CTE生成带编号的临时结果集
- 以编号为1的记录作为主表,左连接编号为2的同客户记录,确保即使没有第二条记录也能保留主记录,对应字段为
NULL
内容的提问来源于stack exchange,提问作者Hoyoko
相关产品推荐
相关产品推荐

