MySQL进阶排序(窗口函数)

您所在的位置:网站首页 sql排序取前十 MySQL进阶排序(窗口函数)

MySQL进阶排序(窗口函数)

#MySQL进阶排序(窗口函数)| 来源: 网络整理| 查看: 265

基本的排序–ORDER BY

Mysql中对数据的排序的基础方法是使用ORDER BY,升序为ASC,逆序为DESC。

mysql> select * from student order by sid asc; //按sid 升序排列 +-------------+-----------+----------+-------+-----+ | sid | sname | major | tid | sex | +-------------+-----------+----------+-------+-----+ | 16451082123 | ZH | math | 17531 | 女 | | 16451082124 | L | computer | 17532 | 男 | | 16451082125 | Z | math | 17533 | 女 | | 16451082126 | M | English | 17532 | 女 | | 16451082127 | ZT | Chinese | 17534 | 女 | | 16451082128 | 王力宏 | math | 17531 | 男 | +-------------+-----------+----------+-------+-----+ 6 rows in set (0.01 sec) mysql> select * from student order by sid desc; //按sid 逆序排列 +-------------+-----------+----------+-------+-----+ | sid | sname | major | tid | sex | +-------------+-----------+----------+-------+-----+ | 16451082128 | 王力宏 | math | 17531 | 男 | | 16451082127 | ZT | Chinese | 17534 | 女 | | 16451082126 | M | English | 17532 | 女 | | 16451082125 | Z | math | 17533 | 女 | | 16451082124 | L | computer | 17532 | 男 | | 16451082123 | ZH | math | 17531 | 女 | +-------------+-----------+----------+-------+-----+ 6 rows in set (0.00 sec) 组内排序

面对数据,有时候我们需要得到数据分组后的排序。

第一反应使用ORDER BY。但是这就会遇到一个问题,如果简单的使用ORDER BY,那么是对全局排序。

故需要对两个字段ORDER BY

mysql> select * from student order by major asc, sid desc; +-------------+-----------+----------+-------+-----+ | sid | sname | major | tid | sex | +-------------+-----------+----------+-------+-----+ | 16451082127 | ZT | Chinese | 17534 | 女 | | 16451082124 | L | computer | 17532 | 男 | | 16451082126 | M | English | 17532 | 女 | | 16451082128 | 王力宏 | math | 17531 | 男 | | 16451082125 | Z | math | 17533 | 女 | | 16451082123 | ZH | math | 17531 | 女 | +-------------+-----------+----------+-------+-----+ 6 rows in set (0.00 sec)

这样我们可以得到最简单的组内排序。

但是现实情况往往更加复杂,比如我需要得到组内排名前10的学生,或者每门选修课程中学生学号最大的前两名。这时候简单的使用GROUP BY、ORDER BY、LIMIT就比较难以实现。

这里我们可以使用一个小技巧,如果是需要对组内数据进行逆序排序取前N个,可以添加一个辅助列,将表进行复制比较,按照分组进行拼接,同时在进行目标行匹配时,比较同个组中的数值大小。也就是说在join on 时有两个条件,通过值的比较,获得组内的大小排名,=得到的是从小到大1,2,3…的顺序。 示例:

mysql> select a.sid,a.major,b.major,b.sid from student a left join student b on a.major = b.major and a.sid select a.sid,a.major,count(*) from student a left join student b on a.major =b.major and a.sid select *, rank() over(partition by major order by tid asc) row_num from student; +-------------+-----------+----------+-------+-----+---------+ | sid | sname | major | tid | sex | row_num | +-------------+-----------+----------+-------+-----+---------+ | 16451082127 | ZT | Chinese | 17534 | 女 | 1 | | 16451082124 | L | computer | 17532 | 男 | 1 | | 16451082126 | M | English | 17532 | 女 | 1 | | 16451082123 | ZH | math | 17531 | 女 | 1 | | 16451082128 | 王力宏 | math | 17531 | 男 | 1 | | 16451082125 | Z | math | 17533 | 女 | 3 | +-------------+-----------+----------+-------+-----+---------+ 6 rows in set (0.00 sec)

dense_rank()排序相同时会重复,总数会减少,意思是会出现1、1、2这样的排序结果。

mysql> select *, dense_rank() over(partition by major order by tid asc) row_num from student; +-------------+-----------+----------+-------+-----+---------+ | sid | sname | major | tid | sex | row_num | +-------------+-----------+----------+-------+-----+---------+ | 16451082127 | ZT | Chinese | 17534 | 女 | 1 | | 16451082124 | L | computer | 17532 | 男 | 1 | | 16451082126 | M | English | 17532 | 女 | 1 | | 16451082123 | ZH | math | 17531 | 女 | 1 | | 16451082128 | 王力宏 | math | 17531 | 男 | 1 | | 16451082125 | Z | math | 17533 | 女 | 2 | +-------------+-----------+----------+-------+-----+---------+


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3