Mysql group by aggregation sort and limit
Mysql group by aggregation sort and limit
我正在尝试找出一个看似微不足道的 SQL 查询。
对于 table 中的所有用户,我想查找时间最长的行(最新事件)的时间和数据。
下面差不多就解决了
SELECT user, MAX(time) as time FROM tasks GROUP BY user;
问题当然是不能减少data
列。因此,我认为我应该使用 WHERE 或 ORDER BY + LIMIT 结构。但是我离我的领域太远了,不知道应该如何正确地完成这件事。有什么提示吗?
注意。在这种情况下无法使用 GROUP BY,因为我想 select 在 table 行 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)
您可以使用子查询进行过滤:
select t.*
from tasks t
where time = (select max(t1.time) from tasks t1 where t1.user = t.user)
此查询将利用 (user, time)
上的 multi-column 索引。
在MySQL 8.0中,你也可以用window函数解决这个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
我正在尝试找出一个看似微不足道的 SQL 查询。 对于 table 中的所有用户,我想查找时间最长的行(最新事件)的时间和数据。
下面差不多就解决了
SELECT user, MAX(time) as time FROM tasks GROUP BY user;
问题当然是不能减少data
列。因此,我认为我应该使用 WHERE 或 ORDER BY + LIMIT 结构。但是我离我的领域太远了,不知道应该如何正确地完成这件事。有什么提示吗?
注意。在这种情况下无法使用 GROUP BY,因为我想 select 在 table 行 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)
您可以使用子查询进行过滤:
select t.*
from tasks t
where time = (select max(t1.time) from tasks t1 where t1.user = t.user)
此查询将利用 (user, time)
上的 multi-column 索引。
在MySQL 8.0中,你也可以用window函数解决这个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