You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL实现:多列分组(ID_1/ID_2/ID_3)下选取每日每组首行

解决多列分组下每日每个建筑取第一行数据的SQL方案

嗨,刚接触SQL碰到这种多列联合标识的分组需求确实容易懵,毕竟大部分入门案例都是单列分组~ 下面给你几个通用且易理解的方案,几乎适配所有主流数据库(MySQL、PostgreSQL、SQL Server等):

方案一:用窗口函数ROW_NUMBER()(最推荐)

这是目前最灵活的解决方案,不管你定义“第一行”的规则是按时间最早、还是其他字段排序,都能轻松实现。核心思路是:

  • 按日期+三个建筑ID作为分组维度(PARTITION BY)
  • 给每个分组内的行按你需要的规则排序(比如按记录生成时间升序,取最早的那条)
  • 筛选出每个分组里排序为1的行

示例SQL代码:

SELECT *
FROM (
    SELECT 
        *,
        -- 按日期和三个ID分组,每组内按create_time升序编号,最早的行编号为1
        ROW_NUMBER() OVER (
            PARTITION BY record_date, ID_1, ID_2, ID_3 
            ORDER BY create_time ASC
        ) AS row_num
    FROM building_records
) AS ranked_records
WHERE row_num = 1;

说明:

  • 把record_date换成你实际的日期列名,create_time换成用来判断“第一行”的排序字段(比如如果没有单独的时间戳,也可以用其他业务字段排序)
  • 如果你的“第一行”规则是取最新的记录,把ORDER BY create_time ASC改成DESC就行

方案二:子查询+关联(适用于有唯一时间戳的场景)

如果你的表有唯一的时间戳字段(比如每条记录的生成时间是唯一的),可以先找出每个建筑每日的最早时间戳,再通过时间戳+建筑ID关联回原表取完整数据:

SELECT br.*
FROM building_records br
INNER JOIN (
    -- 先找到每个日期+建筑ID对应的最早时间戳
    SELECT 
        record_date, 
        ID_1, 
        ID_2, 
        ID_3, 
        MIN(create_time) AS earliest_time
    FROM building_records
    GROUP BY record_date, ID_1, ID_2, ID_3
) AS earliest_records 
ON br.record_date = earliest_records.record_date
AND br.ID_1 = earliest_records.ID_1
AND br.ID_2 = earliest_records.ID_2
AND br.ID_3 = earliest_records.ID_3
AND br.create_time = earliest_records.earliest_time;

说明:

  • 这个方案的前提是create_time在每个record_date+ID_1+ID_2+ID_3分组里是唯一的,否则可能会返回多条相同时间的记录
  • 相比窗口函数,这个方案的可读性稍差,但在某些旧版本数据库(比如MySQL 5.7及以前不支持窗口函数)里是必要的选择

方案三:用DISTINCT ON(仅PostgreSQL支持)

如果你用的是PostgreSQL,还有个更简洁的写法:

SELECT DISTINCT ON (record_date, ID_1, ID_2, ID_3) *
FROM building_records
ORDER BY record_date, ID_1, ID_2, ID_3, create_time ASC;

说明:

  • DISTINCT ON后面跟着的是分组维度,PostgreSQL会返回每个分组里按ORDER BY排序后的第一行数据
  • 注意ORDER BY的开头必须包含DISTINCT ON里的所有字段,否则会报错

内容的提问来源于stack exchange,提问作者MattM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 07:48:23