多语言展示
当前在线:1651今日阅读:84今日分享:32

MySQL中利用简单SQL实现开窗函数的分组排序功能

很多时候,我们会遇到数据分组排序的问题,比如各科成绩排名、各个类别的topN等诸如此类的问题。在Oracle中,我们可以使用开窗函数轻而易举地得到分类及排序的结果,但是MySQL并无此相同功能的函数。要如何实现呢?本文以2016年江苏、浙江、江西三省各市的GDP排序为例,使用简单的SQL语句在MySQL中得到如下图所示的分组排序功能。
工具/原料
1

MySQL

2

Navicat等

方法/步骤
1

对原始数据进行排序:原始数据中,数据可能比较杂乱,并未按照一定的逻辑进行排列,故此时需要重新排序。因为要获得各省分类下,各个市的GDP排名,因此选择按照省名、gpd排序。排序前和排序后分别如图所示。

2

增加变量判断省名是否变化:根据需要的最终结果可知,每个省份下的市单独排序,即当省名变化时,排序号也会相应的发生变化。这就告诉我们,需要判断省名的变化。本例中分别采用@tmp作为中间变量,@rank作为排序号。

3

利用变量进行判断并排序:IF(@tmp=province_name,@rank:=@rank + 1,@rank:=1)则利用中间变量@tmp存储上一条记录的province_name,并和当前的对比,如若相同,则序号@rank增加1,否则初始化@rank为0。@tmp:=province_name则用于将当前的province_name值记录下来,供下一条记录使用。得到排序结果如图。

4

去除中间变量并筛选topN:第三步中的结果不仅有分组排序号,还有中间变量tmp。此步骤中主要对tmp过滤并筛选我们需要的topN,本例采用top3。SELECT province_name,city_name,gdp,new_rank as rank from (SELECT province_name,city_name,gdp,IF(@tmp=province_name,@rank:=@rank + 1,@rank:=1) as new_rank,@tmp:=province_name as tmp FROM `2016_GDP` aORDER BY province_name,gdp DESC) bwhere new_rank <= 3;最终结果如下。

注意事项
1

排名为gdp由高到低,故步骤1中的gdp排序时候需要降序,采用desc

2

ORDER BY province_name,gdp desc对结果至关重要

推荐信息