码迷,mamicode.com
首页 > 数据库 > 详细

SQL Server ->> 间接实现COUNT(DISTINCT XXX) OVER(PARTITION BY YYY ORDER BY ZZZ)

时间:2016-01-14 20:45:24      阅读:387      评论:0      收藏:0      [点我收藏+]

标签:

SQL Server 2005版本开始支持了窗口函数(Windowing Function)和OVER字句。SQL Server 2012版本开始支持了窗口函数的ORDER BY字句实现连续/累计聚合功能。但是有个功能到SQL Server 2014版本为止(从目前SQL Server 2016 CTP3来看,还是不支持),就是COUNT(DISTINCT XXX) OVER(PARTITION BY YYY ORDER BY ZZZ)。

一直觉得这个事情没有办法用比较巧妙地办法做到,只能是用CROSS APPLY或者循环去把数据集“UNION ALL”起来。今天在Google上找到了一个别人想到的办法,顿时觉得自己怎么那么笨,没有想到这个办法呢。巧妙之处在于用一个带有DENSE_RANK函数的子查询配合MAX函数实现。下面是测试代码:

 

CREATE TABLE Foo (
fookey INT PRIMARY KEY,
company VARCHAR(30),
sales_rep VARCHAR(30),
client VARCHAR(30));

INSERT INTO Foo VALUES(1, ABC Corp., Joe, Client1);
INSERT INTO Foo VALUES(2, ABC Corp., Joe, Client2);
INSERT INTO Foo VALUES(6, ABC Corp., Joe, Client2);
INSERT INTO Foo VALUES(3, ABC Corp., Peter, Client2);
INSERT INTO Foo VALUES(4, DEF Corp., Joe, Client1);
INSERT INTO Foo VALUES(5, DEF Corp., Joe, Client3);

SELECT DISTINCT company, sales_rep, client,
MAX(rk1) OVER(PARTITION BY sales_rep) AS rep_distinct_client_cnt,
MAX(rk2) OVER(PARTITION BY company) AS company_distinct_client_cnt
FROM (
SELECT fookey, company, sales_rep, client,
DENSE_RANK() OVER(PARTITION BY sales_rep ORDER BY client) As rk1,
DENSE_RANK() OVER(PARTITION BY company ORDER BY client) As rk2
FROM Foo) AS F;

 

这个办法精妙的地方便是利用了DENSE_RANK本身会对相同值返回相同的排序号的特点,这点恰恰符合了我们需要DISTINCT的作用。其次,排序号和COUNT的相同之处不就是对记录的个数统计吗?那么取得最大的排序号不就相当于拿到了COUNT的值了吗?确实高明。感叹自己过去怎么就没想到呢?还是很开心可以知道这个办法的。

SQL Server ->> 间接实现COUNT(DISTINCT XXX) OVER(PARTITION BY YYY ORDER BY ZZZ)

标签:

原文地址:http://www.cnblogs.com/jenrrychen/p/5131410.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!