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

MySQL技术问询:获取每个用户最新事件的完整行记录

获取每个用户最新任务的完整行数据(MySQL)

我太懂这种烦恼了!用GROUP BY确实只能拿到用户和对应的最新时间,没法直接带出完整的行数据——毕竟MySQL不允许在GROUP BY里直接引用非分组、非聚合的字段(除非改宽松模式配置,但那不是规范的解法)。给你几个靠谱的解决方案,覆盖不同MySQL版本:

方法1:关联子查询(兼容所有MySQL版本)

先通过子查询拿到每个用户的最新时间,再关联回原表匹配对应的完整行:

SELECT t.id, t.user, t.time, t.data
FROM tasks t
INNER JOIN (
    -- 先获取每个用户的最新时间
    SELECT user, MAX(time) AS max_time
    FROM tasks
    GROUP BY user
) tm ON t.user = tm.user AND t.time = tm.max_time;

注意:如果同一个用户有多条记录时间相同且都是最新,这个查询会返回所有这些行。如果要只保留其中一行(比如最新插入的,靠自增id判断),可以把子查询改成SELECT user, MAX(id) AS max_id FROM tasks GROUP BY user,然后关联id = max_id。

方法2:窗口函数(MySQL 8.0+ 推荐使用)

MySQL 8.0及以上支持窗口函数,用ROW_NUMBER()可以直接给每个用户的记录按时间倒序排号,取排号为1的行即可:

SELECT id, user, time, data
FROM (
    SELECT 
        id, user, time, data,
        -- 按用户分组,时间倒序、id倒序排号,确保同一时间取最新插入的行
        ROW_NUMBER() OVER(PARTITION BY user ORDER BY time DESC, id DESC) AS rn
    FROM tasks
) t
WHERE rn = 1;

这个方法最清晰,也能灵活处理同一用户多条最新记录的情况,优先推荐给用新版本MySQL的朋友。

方法3:变量模拟窗口函数(MySQL 5.x 适用)

如果还在使用MySQL 5.x(没有窗口函数),可以用用户变量来实现类似的分组排序效果:

SELECT id, user, time, data
FROM (
    SELECT 
        id, user, time, data,
        -- 当用户和上一行相同时,行号+1;否则重置为1
        @rn := IF(@prev_user = user, @rn + 1, 1) AS rn,
        @prev_user := user
    FROM tasks, (SELECT @prev_user := '', @rn := 0) vars
    -- 先按用户分组,再按时间、id倒序排序
    ORDER BY user, time DESC, id DESC
) t
WHERE rn = 1;

测试验证

用你提供的测试数据运行以上任意一种方法,都能得到预期输出:

+----+-------+------------+--------------+
| id | user  | time       | data         |
+----+-------+------------+--------------+
|  2 | Kalle | 2020-01-01 | latest shit  |
|  3 | Pelle | 1970-01-01 | regular data |
+----+-------+------------+--------------+

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 11:37:29