--1.简介: --SQL Server 中的窗口函数帮助你迅速查看不同级别的聚合,通过它可以非常方便地累计总数、移动平均值、以及执行其它计算。--窗口函数功能非常强大,使用起来也十分容易。可以使用这个技巧立即得到大量统计值。--窗口是用户指定的一组行。 开窗函数计算从窗口派生的结果集中各行的值。--2.适用范围:--排名开窗函数和聚合开窗函数.--也就是说窗口函数是结合排名开窗函数或者聚合开窗函数一起使用--OVER子句前面必须是排名函数或者是聚合函数--3.例题:--建立订单表create table SalesOrder(OrderID int, --订单idOrderQty decimal(18,2) --数量)go--插入数据insert into SalesOrderselect 1,2.0union allselect 1,1.0union allselect 1,3.0union allselect 2,6.0union allselect 2,1.1union allselect 3,8.0union allselect 3,1.1union allselect 3,7.0go--查询得如下结果select * from SalesOrdergo--OrderID OrderQty------------- --------------1 2.00--1 1.00--1 3.00--2 6.00--2 1.10--3 8.00--3 1.10--3 7.00--现要求显示汇总总数,每当所占比例,分组汇总数,每单在各组所占比例,要求格式如下:--OrderID OrderQty 汇总 每单比例 分组汇总 每单在各组比例--1 2.00 29.20 0.0685 6.00 0.3333--1 1.00 29.20 0.0342 6.00 0.1667--1 3.00 29.20 0.1027 6.00 0.5000--2 6.00 29.20 0.2055 7.10 0.8451--2 1.10 29.20 0.0377 7.10 0.1549--3 8.00 29.20 0.2740 16.10 0.4969--3 1.10 29.20 0.0377 16.10 0.0683--3 7.00 29.20 0.2397 16.10 0.4348--利用窗口函数和聚合开窗函数,可以很快实现上述要求select OrderID,OrderQty,sum(OrderQty) over() as [汇总],convert(decimal(18,4), OrderQty/sum(OrderQty) over() ) as [每单所占比例],sum(OrderQty) over(PARTITION BY OrderID) as [分组汇总],convert(decimal(18,4),OrderQty/sum(OrderQty) over(PARTITION BY OrderID)) as [每单在各组所占比例]from SalesOrderorder by OrderID--排名函数 (Transact-SQL) --排名函数为分区中的每一行返回一个排名值。根据所用的函数,某些行可能与其他行接收到相同的值。排名函数具有不确定性。--Transact-SQL 提供下列排名函数:--RANK--NTILE--DENSE_RANK--ROW_NUMBER--rank: 如果两个或多个行与一个排名关联,则每个关联行将得到相同的排名。例如,如果两位顶尖销售员具有同样的 SalesYTD 值,他们将并列第一。由于已有两行排名在前,所以具有下一个最大 SalesYTD 的销售人员将排名第三。因此,RANK 函数并不总返回连续整数。select OrderID,OrderQty,rank()over(partition by OrderID order by OrderQty) 分组排名 ,rank()over(order by OrderQty) 排名from SalesOrder order by OrderID--dense_rank: 如果有两个或多个行受同一个分区中排名的约束,则每个约束行将接收相同的排名。例如,如果两位顶尖销售员具有相同的 SalesYTD 值,则他们将并列第一。接下来 SalesYTD 最高的销售人员排名第二。该排名等于该行之前的所有行数加一。因此,DENSE_RANK 函数返回的数字没有间断,并且始终具有连续的排名。select OrderID,OrderQty,DENSE_RANK()over(partition by OrderID order by OrderQty) 分组排名 ,DENSE_RANK()over(order by OrderQty) 排名from SalesOrder order by OrderID--ntile: 将有序分区中的行分发到指定数目的组中。各个组有编号,编号从一开始。对于每一个行,NTILE 将返回此行所属的组的编号。--例如 共10条数据 ntile(5)over(order by OrderQty) 则排名1-5 每个序号有两条select OrderID,OrderQty,ntile(2)over(partition by OrderID order by OrderQty) 分组排名 ,ntile(3)over(order by OrderQty) 排名from SalesOrder order by OrderID--row_number: 返回结果集分区内行的序列号,每个分区的第一行从 1 开始。--例如选择出每一组中数量最小的数据with a as( select OrderID,OrderQty,ROW_NUMBER()over(partition by OrderID order by OrderQty) as num from SalesOrder) select * from a where a.num=1