MySQL按日期排序并按名称分组

时间:2020-04-19 08:41:32

标签: mysql sql date select sql-order-by

表格

mysql> select * from temp;
+--------+---------------------+
| name   | created_at          |
+--------+---------------------+
| second | 2020-01-01 12:00:00 |
| first  | 2020-01-01 12:10:00 |
| second | 2020-01-01 12:20:00 |
| third  | 2020-01-01 12:30:00 |
| third  | 2020-01-01 12:40:00 |
| first  | 2020-01-01 12:50:00 |
+--------+---------------------+

在上面的示例中,我想先按created_at排序并显示具有相同名称的行。

因此,我尝试使用created_at和name进行订购。

mysql> select * from temp order by created_at, name;
+--------+---------------------+
| name   | created_at          |
+--------+---------------------+
| second | 2020-01-01 12:00:00 |
| first  | 2020-01-01 12:10:00 |
| second | 2020-01-01 12:20:00 |
| third  | 2020-01-01 12:30:00 |
| third  | 2020-01-01 12:40:00 |
| first  | 2020-01-01 12:50:00 |
+--------+---------------------+

但是它不对名称进行分组。

搜索order by之后,我发现在第二列的情况下,它仅应用于第一个order by的结果。

所需结果

+--------+---------------------+
| name   | created_at          |
+--------+---------------------+
| second | 2020-01-01 12:00:00 |
| second | 2020-01-01 12:20:00 |
| first  | 2020-01-01 12:10:00 |
| first  | 2020-01-01 12:50:00 |
| third  | 2020-01-01 12:30:00 |
| third  | 2020-01-01 12:40:00 |
+--------+---------------------+

我该如何操纵查询来实现它?

3 个答案:

答案 0 :(得分:2)

您必须首先按每个命名组的最低created_at进行订购,然后按created_at进行订购。

SELECT name, created_at
FROM TEMP tem
ORDER BY
    (SELECT MIN(tem2.created_at)
     FROM TEMP tem2 
     WHERE tem.name = tem2.name), created_at

每行名称的名称组的下半部分将获得最低created_at

SELECT MIN(tem2.created_at)
         FROM TEMP tem2 
         WHERE tem.name = tem2.name

现在,每个组都按该组的最小created_at进行排序,然后按created_at对每个组的名称进行排序。

答案 1 :(得分:1)

您可以将此表与每个名称最少为created_at的子查询联接,并按以下顺序排序:

SELECT   t.name, created_at
FROM     mytable t
JOIN     (SELECT   name, MIN(created_at) AS min_created_at
          FROM     mytable
          GROUP BY name) m ON t.name = m.name
ORDER BY min_created_at, t.name, t.created_at

答案 2 :(得分:1)

如果运行的是MySQL 8.0,则可以仅使用窗口min()进行订购:

select *
from temp
order by 
    min(created_at) over(partition by name), 
    created_at

在所有具有相同min()的记录中,窗口created_at为您提供了最小的name

在早期版本中,我将直接在order by子句中使用相关子查询:

select *
from temp t
order by
    (select min(t1.created_at) from temp t1 where t1.name = t.name),
    created_at