sql获取group by最后一条记录

获取group by最后一条记录

创建测试表

create table login_log (id int primary key auto_increment, uid int, login_at datetime, login_device varchar(16))

插入数据

INSERT INTO `login_log` (`id`, `uid`, `login_at`, `login_device`) VALUES (1, 1, '2022-04-01 14:34:54', 'PC');
INSERT INTO `login_log` (`id`, `uid`, `login_at`, `login_device`) VALUES (2, 2, '2022-03-01 14:35:08', 'MOBILE');
INSERT INTO `login_log` (`id`, `uid`, `login_at`, `login_device`) VALUES (3, 1, '2022-04-14 14:35:27', 'WEB');
INSERT INTO `login_log` (`id`, `uid`, `login_at`, `login_device`) VALUES (4, 2, '2022-04-30 14:35:35', 'WEB');

查看数据

select * from login_log;
id	uid login_at           	login_device
1	1	2022-04-01 14:34:54	PC
2	2	2022-03-01 14:35:08	MOBILE
3	1	2022-04-14 14:35:27	WEB
4	2	2022-04-30 14:35:35	WEB

group by后默认是获取第一条记录的,

如果只想获取group by后的某个字段的最大值,比如说要获取用户最后的登录时间,那么我们可以:

select uid, max(login_at) as last_login_at from login_log group by uid
uid	last_login_at
1	2022-04-14 14:35:27
2	2022-04-30 14:35:35

但是,我们可能会有这样的需求:获取用户的最后登录时间以及登录设备

你可能会想到:

select uid, max(login_at) as last_login_at, login_device from login_log group by uid

这样是不行的,上面已经提及到group by后默认是会取第一条数据,所以这样查出来的login_device将会是分组后的第一条数据,即用户第一次登录时所使用的设备,而不是最后登录时间所对应的登录设备。

那么有以下几种

解决方案

  • 子查询的方式(可读性最好):
select * from login_log where id in (select max(id) from login_log group by uid)

or

select * from login_log as log1 join (select max(id) as id from login_log group by uid) as log2 where log1.id = log2.id
  • 连表的方式
select log1.* from login_log as log1
left join login_log as log2 on log1.uid = log2.uid and log1.id < log2.id
where log2.id is null
  • exists的方式
select
*
from login_log as log1
where not exists (
  select * from login_log as log2
  where log2.uid = log1.uid
  and log2.Id > log1.Id
)
  • window function的方式(mysql8)
WITH ranked_log AS (
  SELECT log.*, ROW_NUMBER() OVER (PARTITION BY uid ORDER BY id DESC) AS rn
  FROM login_log AS log
)
SELECT * FROM ranked_log WHERE rn = 1;

参考文档:StackOverflow

posted @   Gorgine  阅读(675)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示