row_number()的使用方法 及原博主相关文章。
使用示例:
select calling_nbr,called_nbr,count,
RANK() OVER (PARTITION by calling_nbr order by count desc) rank,
DENSE_RANK() OVER (PARTITION by calling_nbr order by count desc) drank,
ROW_NUMBER() OVER (PARTITION by calling_nbr order by count desc) rn
from test limit 100;
其中 PARTITION by calling_nbr 可选,若加上则是窗口内统计,否则则是全局统计。
部分结果如下:
calling_nbr called_nbr count rank drank rn ---------------------------------------------------------- 00019082203 18997727**2 3 1 1 1 00019082203 18999201**1 2 2 2 2 00019082203 13399086**1 2 2 2 3 00019082203 18909916**2 1 4 3 4 00019082203 18999374**7 1 4 3 5 00019082203 18999887**7 1 4 3 6 00019082203 18999826**8 1 4 3 7 00019082203 18016829**3 1 4 3 8 00019082203 13319869**8 1 4 3 9 00019082203 18999184**5 1 4 3 10 00019082203 18935809**9 1 4 3 11 00019082203 18199117**0 1 4 3 12 00019082203 18099490**6 1 4 3 13 00019082203 18999177**8 1 4 3 14 00019082203 18999584**1 1 4 3 15 00019082203 18999161**6 1 4 3 16 00019082203 18099204**9 1 4 3 17 ---------------------------------------------------------- 00019661102 18935805**8 2 1 1 1 00019661102 18999194**4 2 1 1 2 00019661102 18909974**9 1 3 2 3 00019661102 18997988**9 1 3 2 4 00019661102 18999973**3 1 3 2 5 00019661102 18997522**7 1 3 2 6 00019661102 18999966**8 1 3 2 7 00019661102 18034886**8 1 3 2 8
可以看到以calling_nbr为组进行组内的统计, ROW_NUMBER() 统计当前行号,从1开始; RANK() 为排名统计,若进行排名的值相同则后续留空,如上面的结果中出现了两个2,则接着从4开始; ROW_NUMBER() 与 RANK() 类似,不过出现相同值时不会后续留空,允许“并列第几”的存在。
分片函数,将数据等分为N份,示例如下,将整个表按照count从大到小进行排序并切分成5份。
select calling_nbr,called_nbr,count,
ntile(5) OVER (order by count desc) til
from test;
这样可以通过til=1来选择前1/5的数据,til=2选择1/5到2/5间的数据,以此类推。
验证是否是等分:
select til,count(*) from til5_t group by til;
结果:
1 3152011 2 3152011 3 3152010 4 3152010 5 3152010
类似oracle中的CUME_DIST和PERCENT_RANK函数,用来计算分组中的位置,数值介于0和1之间。
示例:
select calling_nbr,called_nbr,count,
RANK() OVER (PARTITION by calling_nbr order by count desc) rank,
DENSE_RANK() OVER (PARTITION by calling_nbr order by count desc) drank,
ROW_NUMBER() OVER (PARTITION by calling_nbr order by count desc) rn,
CUME_DIST() OVER (PARTITION by calling_nbr order by count desc) dist,
PERCENT_RANK() OVER (PARTITION by calling_nbr order by count desc) prank
from test limit 100;
结果(只选取了一组):
00019639213 13364908300 2 1 1 1 0.043478260869565216 0.0 00019639213 15352666868 1 2 2 2 1.0 0.045454545454545456 00019639213 18099189171 1 2 2 3 1.0 0.045454545454545456 00019639213 18999908156 1 2 2 4 1.0 0.045454545454545456 00019639213 18999682115 1 2 2 5 1.0 0.045454545454545456 00019639213 18999033733 1 2 2 6 1.0 0.045454545454545456 00019639213 18999412012 1 2 2 7 1.0 0.045454545454545456 00019639213 18999499678 1 2 2 8 1.0 0.045454545454545456 00019639213 13319708861 1 2 2 9 1.0 0.045454545454545456 00019639213 18097711665 1 2 2 10 1.0 0.045454545454545456 00019639213 18099721994 1 2 2 11 1.0 0.045454545454545456 00019639213 15389923573 1 2 2 12 1.0 0.045454545454545456 00019639213 18935754120 1 2 2 13 1.0 0.045454545454545456 00019639213 18196110916 1 2 2 14 1.0 0.045454545454545456 00019639213 18099189175 1 2 2 15 1.0 0.045454545454545456 00019639213 18099023200 1 2 2 16 1.0 0.045454545454545456 00019639213 18999446189 1 2 2 17 1.0 0.045454545454545456 00019639213 18999685463 1 2 2 18 1.0 0.045454545454545456 00019639213 18999793295 1 2 2 19 1.0 0.045454545454545456 00019639213 13319873344 1 2 2 20 1.0 0.045454545454545456 00019639213 13319706226 1 2 2 21 1.0 0.045454545454545456 00019639213 18016893222 1 2 2 22 1.0 0.045454545454545456 00019639213 18999528429 1 2 2 23 1.0 0.045454545454545456
其中CUME_DIST的计算方式为 分组所在位置/分组大小 ,如1/23=0.043478260869565216,23/23=1.0。PERCENT_RANK的计算方式为 (分组中顺序-1)/(分组大小-1),如(1-1)/(23-1)=0.0,(2-1)/(23-1)=0.045454545454545456。
上面已经用到了 OVER 关键字,除了上面的用法以外,还有更强大的窗口选择关键字 ROWS 。用法: ROWS ((CURRENT ROW) | (UNBOUNDED | [num]) PRECEDING) AND (UNBOUNDED | [num]) FOLLOWING 。
举例,数据:
1 D 67 1 B 11 2 A 76 2 Y 22 1 C 7 3 M 15 2 K 65 2 U 26 2 I 54 2 T 12 2 D 8 1 A 10 3 J 1
建表语句:
create table test(
calling string,
called string,
duration int
) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
使用ROWS关键字:
select calling,called,
sum(duration) OVER (PARTITION by calling order by duration desc ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
from test;
结果:
1 D 78 1 B 88 1 A 28 1 C 17 2 A 141 2 K 195 2 I 145 2 U 102 2 Y 60 2 T 42 2 D 20 3 M 16 3 J 16
此时对照原始数据完全看不出来是什么意思,在使用ROWS时根据duration进行了组内的排序,这里将排序的结果展示出来:
1 D 67 1 B 11 1 A 10 1 C 7 2 A 76 2 K 65 2 I 54 2 U 26 2 Y 22 2 T 12 2 D 8 3 M 15 3 J 1
此时在看ROWS后面参数的含义,意思是从前1行开始到后1行结束,也就是窗口的大小限制成为3。结合结果数据和排序后的数据来开,当没有前一行的时候,窗口大小变成2,即当前行和后一行,如结果数据中第一行的78=67(当前行)+11(后一行),第二行88=67(前一行)+11(当前行)+10(后一行),当没有后一行时情况类似。
此外可以用 CURRENT ROW 限制成当前行,用 UNBOUNDED PRECEDING或FOLLOWING 来表示不限制前/后面的行数。一个典型的不限制前面行数的应用就是按月累积统计值,如1月的收入、2月的累积收入(包括1月)、3月的累积收入..