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

MySQL中按(user,a,b)分组获取每组最新行数据

没问题,我来帮你搞定这个SQL查询的问题~

问题背景

我有一张名为foo的表,表结构如下:

+----------+--------------+------+-----+-------------------+----------------+
| Field    | Type         | Null | Key | Default           | Extra          |
+----------+--------------+------+-----+-------------------+----------------+
| id       | int(10)      | NO   | PRI | NULL              | auto_increment |
| ts       | timestamp    | NO   |     | CURRENT_TIMESTAMP |                |
| user     | varchar(255) | YES  | MUL | NULL              |                |
| a        | varchar(255) | YES  | MUL | NULL              |                |
| b        | varchar(255) | YES  | MUL | NULL              |                |
| c        | float        | YES  |     | NULL              |                |
+----------+--------------+------+-----+-------------------+----------------+

需求:针对每一组不同的(user,a,b),选取最新的timestamp(ts)以及对应的c值。

我尝试了如下SQL语句的多种变体,但均未成功:

select distinct user, b, c, ts as ts_b from (select max(ts) as ts_a from foo as max_ts) where ts_a = ts_b;

解决方案

你的原始SQL逻辑存在两个关键问题:一是子查询没有按(user,a,b)分组,只算了全表的最大时间戳;二是子查询和主表没有关联关系,根本无法匹配到对应分组的最新记录。下面给你几种可行的解决方法:

方法1:窗口函数(MySQL 8.0+ 首推)

如果你的MySQL版本是8.0及以上,用ROW_NUMBER()窗口函数是最直观高效的方式:

SELECT user, a, b, ts, c
FROM (
    SELECT 
        user, a, b, ts, c,
        -- 按user,a,b分组,每组内按ts从新到旧排序,给每条记录打序号
        ROW_NUMBER() OVER (PARTITION BY user, a, b ORDER BY ts DESC) AS rn
    FROM foo
) t
-- 只取每组的第一条(序号为1的就是最新记录)
WHERE rn = 1;

方法2:关联子查询(兼容低版本MySQL)

要是你用的是低于8.0的MySQL,不支持窗口函数,可以先分组拿到每个(user,a,b)的最新时间戳,再关联原表获取对应的c值:

SELECT f.user, f.a, f.b, f.ts, f.c
FROM foo f
INNER JOIN (
    -- 先按user,a,b分组,计算每组的最大ts
    SELECT user, a, b, MAX(ts) AS max_ts
    FROM foo
    GROUP BY user, a, b
) t 
-- 通过user,a,b和ts关联,拿到对应记录的c值
ON f.user = t.user AND f.a = t.a AND f.b = t.b AND f.ts = t.max_ts;

方法3:子查询匹配(简洁写法)

还有一种更简洁的写法,直接在WHERE子句中匹配同分组的最大时间戳:

SELECT f.user, f.a, f.b, f.ts, f.c
FROM foo f
WHERE f.ts = (
    -- 找到当前记录同user,a,b分组下的最大ts
    SELECT MAX(ts)
    FROM foo
    WHERE user = f.user AND a = f.a AND b = f.b
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:56:59