MySQL中分组后选择首行
2021-01-13 08:31
本文共约 429 字
预计阅读时间约 1 分钟
在数据库表操作中,一个常见的需求是:如何按照创建时间,取出每天的第一条的记录。
然而,这并不是单纯依靠标准SQL语法就能完成的,而需要配合特定数据库实现的函数辅助才行。在MySQL中,这个函数即ROW_NUMBER()。
下面用一个临时创建的表,具体展示下用法:
1$ mysql
2
3mysql> create table test0113 (grp int, value float);
4Query OK, 0 rows affected (0.13 sec)
5
6mysql> insert into test0113 values (1, .1), (1, .2), (1, .3), (2, .2), (2, .4);
7Query OK, 5 rows affected (0.02 sec)
8Records: 5 Duplicates: 0 Warnings: 0
9
10mysql> select * from test0113;
11+------+-------+
12| grp | value |
13+------+-------+
14| 1 | 0.1 |
15| 1 | 0.2 |
16| 1 | 0.3 |
17| 2 | 0.2 |
18| 2 | 0.4 |
19+------+-------+
205 rows in set (0.00 sec)ROW_NUMBER()需要配合OVER (PARTITION BY ... ORDER BY ...)的语法结构,来实现所需查询:
1mysql> select grp, value, row_number() over (partition by grp order by value) row_num from test0113 order by grp, value;
2+------+-------+---------+
3| grp | value | row_num |
4+------+-------+---------+
5| 1 | 0.1 | 1 |
6| 1 | 0.2 | 2 |
7| 1 | 0.3 | 3 |
8| 2 | 0.2 | 1 |
9| 2 | 0.4 | 2 |
10+------+-------+---------+
115 rows in set (0.00 sec)有了这个结果后,再配合一层嵌套查询,就可以实现最开始的需求了:
1mysql> select * from (select grp, value, row_number() over (partition by grp order by value) row_num from test0113 order by grp, value) t1 where row_num = 1;
2+------+-------+---------+
3| grp | value | row_num |
4+------+-------+---------+
5| 1 | 0.1 | 1 |
6| 2 | 0.2 | 1 |
7+------+-------+---------+
82 rows in set (0.00 sec)参考: