sqlserver 开窗函数over RANK(),DENSE_RANK(),ROW_NUMBER()三个排序的不同

一、开窗函数over()

开窗函数适用于在每一行的最后一列添加聚合函数的结果。开窗函数在group by 后只能 对select 后面的能出现的列进行操作,没group by 可以对select后面出现的列进行操作

常用开窗函数:
1.为每条数据显示聚合信息.(聚合函数() over())
2.为每条数据提供分组的聚合函数结果(聚合函数() over(partition by 字段) as 别名) --按照字段分组,分组后进行计算
3.与排名函数一起使用(row number() over(order by 字段) as 别名)

常用分析函数:(最常用的应该是1.2.3 的排序)
1、row_number() over(partition by ... order by ...)
2、rank() over(partition by ... order by ...)
3、dense_rank() over(partition by ... order by ...)
4、count() over(partition by ... order by ...)
5、max() over(partition by ... order by ...)
6、min() over(partition by ... order by ...)
7、sum() over(partition by ... order by ...)
8、avg() over(partition by ... order by ...)
9、first_value() over(partition by ... order by ...)
10、last_value() over(partition by ... order by ...)
11、lag() over(partition by ... order by ...)
12、lead() over(partition by ... order by ...)
lag 和lead 可以 获取结果集中,按一定排序所排列的当前行的上下相邻若干offset 的某个行的某个列(不用结果集的自关联);
lag ,lead 分别是向前,向后;
lag 和lead 有三个参数,第一个参数是列名,第二个参数是偏移的offset,第三个参数是 超出记录窗口时的默认值)

example:

CREATE TABLE STU(  
   id INT IDENTITY,
   name VARCHAR(50),
   score INT,
   subject VARCHAR(50)
)
INSERT INTO bi.dbo.STU
( name, score,subject)
VALUES
( 'tom', 20,'数学'),
('jerry',60,'英语'),
('bob',30,'语文'),
('marry',30,'语文'),
('lucy',60,'物理'),
('bob',90,'英语'),
('tom',50,'英语'),
('jerry',50,'物理')


SELECT *,AVG(score) over(PARTITION BY name  (ORDER BY id)) FROM  bi.dbo.STU    结果为:

tips:1、如果为每条数据提供分组的聚合函数结果(聚合函数() over(partition by 字段) as 别名),就不要加order by ,

会导致每个分组的最后一行才有聚合结果

2、与排名函数一起使用(row number() over(order by 字段) as 别名),加order by

 聚合结果只能有一个,如果select后面要跟多个avg,则只能再用子查询,跟开窗函数

和group by的区别,

SELECT *,AVG(score) over(PARTITION BY name ) FROM  bi.dbo.STU;

select后面可以加未分组的字段,因为over把聚合结果变成多行

SELECT *, SUM(score) OVER () FROM bi.dbo.STU group by name 

会报错,因为sum(score)是一行,而*是多行。 

在分页中的运用

 用子查询:
  10  ,  5
  SELECT  top  5  *  FROM   bi_dirty.dbo.policy_report  WHERE  ID  NOT  IN
 ( SELECT  top  10  ID  FROM  bi_dirty.dbo.policy_report  ORDER  BY  publish_date)   ORDER  BY  publish_date

 用over()

SELECT  *  FROM
(  SELECT  *, ROW_NUMBER ()  OVER  ( ORDER  BY  publish_date)  AS  num  FROM  bi_dirty.dbo.policy_report) t
  where  t.num  BETWEEN  11  AND  15


二、RANK(),DENSE_RANK(),ROW_NUMBER()三个排序的不同

SELECT 

s.deptno,s.ename,s.sal,
RANK() over(partition by s.deptno order by s.sal) as rank,
DENSE_RANK() over(partition by s.deptno order by s.sal) as dense_rank,
ROW_NUMBER() over(partition by s.deptno order by s.sal) as row_number
FROM emp s;

这是一个查询每个部门员工工资的排序情况

从查询结果中很明显的发现规律:

RANK()                        发生不持续的编号 例如数据值 1,2,2,3 发生的编号将是1,2,2,4

DENSE_RANK()        发生持续的编号 例如数据值 1,2,2,3 发生的编号将是1,2,2,3

ROW_NUMBER()     发生持续的编号(不重复) 例如数据值 1,2,2,3 发生的编号将是1,2,3,4

RANK()  和 DENSE_RANK() 排序的差异就是排序存在并列的情况下。
————————————————
版权声明:本文为CSDN博主「张明贵」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/lifewinnerforever/article/details/72868071

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值