如何在SQL中合并同一分组下首行与末行的指定字段?
我来帮你搞定这个需求!要实现每个id分组取首行的enter_date,其他字段取末行的数据,核心是先给每个分组的行做排序标记,再把首末行的对应字段拼起来。下面分几种常用的SQL场景给你解法:
方法一:用窗口函数(适用于MySQL 8.0+、PostgreSQL、SQL Server等)
这是最简洁高效的方式,用ROW_NUMBER()给每个分组的行按顺序编号,区分首行和末行,再通过聚合提取目标字段。
完整SQL代码
WITH ranked_data AS ( SELECT id, enter_date, exit_date, money, -- 标记分组内的首行(按日期升序排序后的第一行) ROW_NUMBER() OVER (PARTITION BY id ORDER BY enter_date, exit_date) AS rn_asc, -- 标记分组内的末行(按日期降序排序后的第一行) ROW_NUMBER() OVER (PARTITION BY id ORDER BY enter_date DESC, exit_date DESC) AS rn_desc FROM your_table ) SELECT id, -- 提取首行的enter_date MAX(CASE WHEN rn_asc = 1 THEN enter_date END) AS enter_date, -- 提取末行的exit_date MAX(CASE WHEN rn_desc = 1 THEN exit_date END) AS exit_date, -- 提取末行的money MAX(CASE WHEN rn_desc = 1 THEN money END) AS money FROM ranked_data GROUP BY id;
方法二:兼容老版本MySQL(无窗口函数支持)
如果你的MySQL版本低于8.0,不支持窗口函数,可以用子查询的方式直接取分组内的首末行字段:
SELECT t.id, -- 取分组下首行的enter_date (SELECT enter_date FROM your_table WHERE id = t.id ORDER BY enter_date, exit_date LIMIT 1) AS enter_date, -- 取分组下末行的exit_date (SELECT exit_date FROM your_table WHERE id = t.id ORDER BY enter_date DESC, exit_date DESC LIMIT 1) AS exit_date, -- 取分组下末行的money (SELECT money FROM your_table WHERE id = t.id ORDER BY enter_date DESC, exit_date DESC LIMIT 1) AS money FROM (SELECT DISTINCT id FROM your_table) t;
关键注意点
- 排序逻辑要贴合业务:示例里用
enter_date, exit_date排序确定首末行,如果你的表有主键或创建时间字段,优先用这些字段排序,避免因日期重复导致行顺序混乱。 - 分组内只有一行数据时,两种方法都会自动保留该行的所有字段,完全符合预期。
内容的提问来源于stack exchange,提问作者seb
相关产品推荐
相关产品推荐

