一组行称为一个窗口,开窗函数是可以用于分区计算的函数,分为聚合函数和排名函数,分别可以放在OVER子句前以对组内的数据进行编号和运算。
注:本节”窗”就是指”分区”。
聚合函数与OVER子句
聚合函数是对一组值执行计算并返回单一的值的函数。如SUM()、AVG()、MIN()、MAX()。
SELECT 列名表,
聚合函数(参数列名) OVER(PARTITION BY 分区依据列) AS '生成列名',
聚合函数(参数列名) OVER(PARTITION BY 分区依据列) AS '生成列名',
...
聚合函数(参数列名) OVER(PARTITION BY 分区依据列) AS '生成列名'
FROM 表名
例如:
select Cno,CName,Semester,Credit,
SUM(Credit) over(partition by Semester) as '学期总学分',
AVG(Credit) over(partition by Semester) as '平均学分',
MIN(Credit) over(partition by Semester) as '最小学分',
MAX(Credit) over(partition by Semester) as '最大学分'
from Course
又如:
select OrderID 订单号,ProductID 产品号,Num 订购数量,
SUM(Num) over(partition by ProductID) AS '该类产品共订了',
CAST(
1.0*Num/
(SUM(Num) over(partition by ProductID))
*100
as decimal(5,2)
) AS '所占百分比'
from OrderTab
排名函数与OVER子句
排名函数是为分区中的每一行返回一个排名值的函数。SQL Server中的排名函数有:RANK()、DENSE_RANK()、NTILE、ROW_NUMBER。
①RANK()、DENSE_RANK()、ROW_NUMBER函数
这三个函数功能类似,都是对分区后的窗按一个排序依据列内排序,并生成新的列,它们的语法也一致:
SELECT 列名表,
函数名() OVER(PARTITION BY 分区依据列
ORDER BY 排序依据列 [DESC]) AS '生成列名',
函数名() OVER(PARTITION BY 分区依据列
ORDER BY 排序依据列 [DESC]) AS '生成列名',
...
函数名() OVER(PARTITION BY 分区依据列
ORDER BY 排序依据列 [DESC]) AS '生成列名'
FROM 表名
[ORDER BY 有时需以分区依据列做外排 [DESC]]
例如:
select OrderID 订单号,ProductID 产品号,Num 订购数量,
RANK() over(partition by ProductID
order by Num desc) AS 'RANK排名列',
DENSE_RANK() over(partition by ProductID
order by Num desc) AS 'DENSE_RANK排名列',
ROW_NUMBER() over(partition by ProductID
order by Num desc) AS 'ROW_NUMBER排名列'
from OrderTab
②NTILE()函数
尝试等分成几块,并生成新的列:
SELECT 列名表,
NTILE(划分块数) OVER([PARTITION BY 如果需分窗分别处理此处应指定]
ORDER BY 排序依据列 [DESC]) AS '生成列名'
FROM 表名
[ORDER BY 有时可以根据需求做外排 [DESC]]
这个函数用得很少,它会尽量尝试等分,注意不使用OVER内的PATTERN BY时,它就与开窗无关了,仅仅是做整体性的尝试等分。
例如:
select OrderID 订单号,ProductID 产品号,Num 订购数量,
NTILE(4) over(order by Num desc) AS 'NTILE划分列'
from OrderTab