如何通过 created_at 对一组行进行排序?

Posted

技术标签:

【中文标题】如何通过 created_at 对一组行进行排序?【英文标题】:How to order a group of rows by created_at? 【发布时间】:2021-06-23 17:03:43 【问题描述】:

我的访问表如下所示:

id name isp created_at
1 Jack Comcast 2021-03-13 01:00:00
2 Jack Comcast 2021-03-13 01:01:00
3 Tom Comcast 2021-03-13 01:02:00
4 Jill Amazon 2021-03-13 01:03:00
5 Jack Comcast 2021-03-13 01:50:00
6 Jill Amazon 2021-03-13 01:06:00
7 Jack Comcast 2021-03-14 01:00:00

我想将“isp”分组在一起,然后根据每个组和组内第一行的最新 created_at 对组进行排序,按“created_at”和“名称”排序。结果表应如下所示

id name isp created_at
1 Jack Comcast 2021-03-13 01:00:00
2 Jack Comcast 2021-03-13 01:01:00
5 Jack Comcast 2021-03-13 01:50:00
7 Jack Comcast 2021-03-14 01:00:00
3 Tom Comcast 2021-03-13 01:02:00
4 Jill Amazon 2021-03-13 01:03:00
6 Jill Amazon 2021-03-13 01:06:00

我有以下代码要按“isp”排序,但我一直坚持如何根据第一个“created_at”对 isp 组进行排序。

SELECT * FROM visits
ORDER BY isp

【问题讨论】:

...在每组第一行的最新 created_at... 是最新的还是最早的? 最新的 【参考方案1】:

如果您的 mysql 版本是 8.0+,请在 ORDER BY 子句中使用 MAX() 窗口函数:

SELECT *
FROM visits
ORDER BY MAX(created_at) OVER (PARTITION BY isp) DESC, name, created_at

对于早期版本,请使用相关子查询:

SELECT v1.*
FROM visits v1
ORDER BY (SELECT MAX(v2.created_at) FROM visits v2 WHERE v2.isp = v1.isp) DESC, 
         name, created_at

请参阅demo。

id name isp created_at
1 Jack Comcast 2021-03-13 01:00:00
2 Jack Comcast 2021-03-13 01:01:00
5 Jack Comcast 2021-03-13 01:50:00
7 Jack Comcast 2021-03-14 01:00:00
3 Tom Comcast 2021-03-13 01:02:00
4 Jill Amazon 2021-03-13 01:03:00
6 Jill Amazon 2021-03-13 01:06:00

【讨论】:

【参考方案2】:

你可以使用窗口函数:

order by max(created_at) over (partition by ip) desc,
         ip,
         max(created_at) over (partition by ip, name) desc,
         name,
         created_at desc

这些键是什么?

created_atip 的最大值。 然后是ip,所以在出现平局时,给定ip 的所有行都在一起。 每个ip 的每个名称的最大created_at。 然后是name,这样每个名字的行就在一起了。 最后,created_at

【讨论】:

以上是关于如何通过 created_at 对一组行进行排序?的主要内容,如果未能解决你的问题,请参考以下文章

对表格进行排序,但将多组行放在一起

如何仅在该特定组内按结果查找组中未排序的一组行?

如何对一组 IP 地址 进行排序?

如何对一组点进行排序,以便它们一个接一个地设置?

如何根据列中的一组行对数据框进行排名?

C语言链表中如何实现对一组数据进行排序?