首页 > 解决方案 > Mysql group by 聚合排序和限制

问题描述

我试图找出一个看似微不足道的 SQL 查询。对于表中的所有用户,我想找到时间最长的行(最新事件)的时间和数据。

以下几乎解决了它

SELECT user, MAX(time) as time FROM tasks GROUP BY user;

问题当然是data不能减少列。我认为因此我应该使用 WHERE 或 ORDER BY + LIMIT 结构。但是我离我的领域太远了,不知道应该如何正确完成。有什么提示吗?

笔记。在这种情况下无法使用 GROUP BY,因为我想在表行 ID 上进行选择,显然无法聚合。

-- MYSQL

DROP DATABASE IF EXISTS test;
CREATE DATABASE test;
USE test;

CREATE TABLE tasks (
    id int AUTO_INCREMENT,
    user varchar(100) NOT NULL,
    time date NOT NULL,
    data varchar(100) NOT NULL,
    PRIMARY KEY (id)
);

INSERT INTO tasks (user, time, data) VALUES
    ("Kalle", "1970-01-01", "old news"),
    ("Kalle", "2020-01-01", "latest shit"),
    ("Pelle", "1970-01-01", "regular data");

-- Expected output
-- +----+-------+------------+--------------+
-- | id | user  | time       | data         |
-- +----+-------+------------+--------------+
-- |  2 | Kalle | 2020-01-01 | latest shit  |
-- |  3 | Pelle | 1970-01-01 | regular data |
-- +----+-------+------------+--------------+
-- 2 rows in set (0.00 sec)

标签: mysqlsqldatetimesubquerygreatest-n-per-group

解决方案


您可以使用子查询进行过滤:

select t.* 
from tasks t
where time = (select max(t1.time) from tasks t1 where t1.user = t.user)

此查询将利用(user, time).

在 MySQL 8.0 中,您还可以使用窗口函数解决此 top-1-per-group:

select *
from (select t.*, row_number() over(partition by user order by time desc) rn from tasks t) t
where rn = 1

推荐阅读