Table
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 |
+--------+---------------------+
In the above example, I want to order by created_at
first and show rows with the same name.
So I trying to ordering with 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 |
+--------+---------------------+
But it does not grouping name.
After searched about order by, I found that in the case of the second column, it is applied only to the result of the first order by.
Desired result
+--------+---------------------+
| 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 |
+--------+---------------------+
How can I manipulate query to achieve it?
You have to order by minimum created_at
of every named group first then order by 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
Bellow part will get minimum created_at
for name group of every row's name
SELECT MIN(tem2.created_at)
FROM TEMP tem2
WHERE tem.name = tem2.name
Now every group is ordered by the group's minimum created_at
and then order every group name's by created_at
.
You could join this table with a subquery of the minimal created_at
per name, and order by that:
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
If you are running MySQL 8.0, you can just use window min()
for ordering:
select *
from temp
order by
min(created_at) over(partition by name),
created_at
The window min()
gives you the minimum created_at
across all records that have th same name
.
In earlier versions, I would use a correlated subquery directly in the order by
clause:
select *
from temp t
order by
(select min(t1.created_at) from temp t1 where t1.name = t.name),
created_at
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.