• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 众包
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
thankgoodness
博客园    首页    新随笔    联系   管理    订阅  订阅

MS-SQL Server2005的几个新函数

ROW_NUMBER 函数 [集合]
CUME_DIST 函数 [集合]
DENSE_RANK 函数 [集合]
PERCENT_RANK 函数 [集合]
RANK 函数 [集合]

1、ROW_NUMBER 函数 [集合]

功能
对每一行分配一个唯一的编号。

语法
ROW_NUMBER ( )

示例
下面的示例返回了一个为每一个 Utah 和 New York 州的职员提供唯一行号的结果集。由于该查询按薪水降序排序,所以第一个行号赋予给了数据集中薪水最高的职员。尽管有两名职员具有相同的薪水,但是并没有解析关联,因为这两名职员被分配了唯一的行号。

SELECT emp_lname, salary, state,
ROW_NUMBER () OVER (ORDER BY salary DESC) "Rank"
FROM employee WHERE state IN ('NY','UT')
下面是结果集:

emp_lname salary state Rank
Shishov 72995.000 UT 1
Wang 68400.000 UT 2
Cobb 62000.000 UT 3
Morris 61300.000 UT 4
Davidson 57090.000 NY 5
Martel 55700.000 NY 6
Blaikie 54900.000 NY 7
Diaz 54900.000 NY 8
Driscoll 48023.690 UT 9
Hildebrand 45829.000 UT 10
... ... ... ...
Lynch 24903.000 UT 19

2、CUME_DIST 函数 [集合]

功能
计算某个值在一组行中的相对位置。它返回介于 0 和 1 之间的小数值。

语法
CUME_DIST ( )

用法
目前在 CUME_DIST 函数中还不允许使用组合排序键。您可以在任何其它秩函数中使用组合排序键。

示例
下面的示例返回一个包含居住在 California 的职员的薪水累计分布的结果集。

SELECT dept_id, emp_lname, salary,
CUME_DIST () OVER (PARTITION BY dept_id
ORDER BY salary DESC) "Rank"
FROM employee
WHERE state IN ('CA')
下面是结果集:

dept_id emp_lname salary Rank
200 Savarino 72300.000 0.333333333333333
200 Clark 45000.000 0.666666666666667
200 Overbey 39300.000 1


3、DENSE_RANK 函数 [集合]

功能
计算一个分区中的值的秩。对于并列的数值,DENSE_RANK 在排名序列中不会留有空位。

语法
DENSE_RANK ( )

示例
下面的示例返回了一个包含 Utah 和 New York 州的职员薪水排位的结果集。尽管在返回的结果集中包含 19 条记录,但只列出了 18 个排位,因为在列表中第 7 名职员与第 8 名具有相同的薪水而并列第 7 位。因为 DENSE_RANK 函数不会在排位中留有空位,所以第 9 名职员的排位为 '8' 而不是 '9'。

SELECT dept_id, emp_lname, salary, state,
DENSE_RANK () OVER (ORDER BY salary DESC) "Rank"
FROM employee
WHERE state IN ('NY','UT')
下面是结果集:

emp_lname salary state Rank
Shishov 72995.000 UT 1
Wang 68400.000 UT 2
Cobb 62000.000 UT 3
Morris 61300.000 UT 4
Davidson 57090.000 NY 5
Martel 55700.000 NY 6
Blaikie 54900.000 NY 7
Diaz 54900.000 UT 7
Driscoll 48023.000 UT 8
Hildebrand 45829.000 UT 9
Whitney 45700.000 NY 10
Guevara 42998.000 NY 11
Soo 39075.000 NY 12
Goggin 37900.000 UT 13
Wetherby 35745.000 NY 14
Ahmed 34992.000 NY 15
Rebeiro 34576.000 UT 16
Bigelow 31200.000 UT 17
Lynch 24903.000 UT 18

4、PERCENT_RANK 函数 [集合]

功能
计算由 ORDER BY 子句定义,在返回的查询中某一行相对于其它行的(小数)位置。它返回介于 0 和 1 之间的小数值。

语法
PERCENT_RANK ( )

示例
下面的示例返回了根据性别列出的 New York 的职员薪水排位结果集。该结果使用百分比数按降序列出排位并按性别分区。

SELECT dept_id, emp_lname, salary, sex,
PERCENT_RANK () OVER (PARTITION BY sex
ORDER BY salary DESC) "Rank"
FROM employee
WHERE state IN ('NY')
下面是结果集:

dept_id emp_lname salary sex Rank
200 Martel 55700.000 M 0
100 Guevara 42998.000 M 0.333333333
100 Soo 39075.000 M 0.666666667
400 Ahmed 34992.000 M 1
300 Davidson 57090.000 F 0
400 Blaikie 54900.000 F 0.333333333
100 Whitney 45700.000 F 0.666666667
400 Wetherby 35745.000 F 1


5、RANK 函数 [集合]

功能
计算一组值中的一个秩的值。对于出现并列的情况,RANK 会在排名序列中留有空位。

语法
RANK ( )

示例
下面的示例提供了 Utah 和 New York 州的职员薪水降序排位。注意到第 7 名职员与第 8 名具有相同的薪水因而并列第 7 位。接下来的职员的排位为第 9 位而在排位序列中留下了空位(没有第 8 位排位)。

SELECT emp_lname, salary, state,
RANK () OVER (ORDER BY salary DESC) "Rank"
FROM employee WHERE state IN ('NY','UT')
下面是结果集:

emp_lname salary state Rank
Shishov 72995.000 UT 1
Wang 68400.000 UT 2
Cobb 62000.000 UT 3
Morris 61300.000 UT 4
Davidson 57090.000 NY 5
Martel 55700.000 NY 6
Blaikie 54900.000 NY 7
Diaz 54900.000 NY 7
Driscoll 48023.690 UT 9
Hildebrand 45829.000 UT 10
Whitney 45700.000 NY 11
... ... ... ...
Lynch 24903.000 UT 19

6、PIVOT 行列转换

CREATE TABLE E_money (work_no varchar(6),moeny_type varchar(10),num int )

work_no money_type num
100001HKD      100
100001HKD      200
100001USD      300
200020HKD      50
200020RMB      5000
200020USD      500
400078HKD      80
400078HKD      90
400078RMB      800
400078RMB      900
400078USD      90
400078USD      800


--统计每个员工不同币种拥有数
work_no 港币       美元       人民币
10000130030050
200020505005000
4000781708901700


--sql 2000写法
select work_no,
sum(case when moeny_type='HKD' then num else 0 end) as 港币,
sum(case when moeny_type='USD' then num else 0 end) as 美元,
sum(case when moeny_type='RMB' then num else 0 end) as 人民币
from e_money
group by work_no

--2005新增函数
SELECT
work_no,
[HKD] as 港币,
[USD] as 美元,
[RMB] as 人民币
FROM e_money
PIVOT(SUM(num) FOR moeny_type IN([HKD],[USD],[RMB])) AS pvt

7、NTILE(N) 将结果分成N个组

SELECT A,B ,C,MyGroup=NTILE(10) OVER(ORDER BY BirthDate DESC) --将结果分成10个组

-----------------------------

SELECT
    YEAR(BirthDate),
    ROW_NUMBER() OVER(ORDER BY YEAR(BirthDate)) AS 'RowNumber',/**//* 按年产生一个唯一的序号 */
    ROW_NUMBER() OVER(PARTITION BY YEAR(BirthDate) ORDER BY BirthDate) AS RowNumberPartition, /**//* 每年产生一个唯一的序列 */
    RANK() OVER(ORDER BY YEAR(BirthDate)) AS 'Rank', /**//* 产生一个非紧密排名 */
    DENSE_RANK() OVER(ORDER BY YEAR(BirthDate)) AS 'Dense_Rank', /**//* 产生一个紧密排名 */
    NTILE(10) OVER(ORDER BY BirthDate DESC) AS 'ntile' /**//* 将结果分成10个组 */
FROM HumanResources.Employee
ORDER BY BirthDate
看看新的排序函数如何解决SQL server 2000中不方便解决的问题
--按BirthDate排序,取第10条到20条的数据 (这一定是最激动人心的新特性,哈哈)
SELECT BirthDate FROM
(
    SELECT
        ROW_NUMBER() OVER(ORDER BY BirthDate) AS a,BirthDate
    FROM HumanResources.Employee
) AS a
WHERE a BETWEEN 10 AND 20

--将数据分成十份,取第三份
SELECT
    BirthDate
FROM
(
SELECT
    NTILE(10) OVER(ORDER BY BirthDate DESC) AS a,BirthDate
FROM HumanResources.Employee
) AS a
WHERE a = 3再来看看如何用新的排序函数解决以前在SQL server 2000中的问题
-- 出生的员工最多的一年出生多少员工(有点)
/**//* SQL server 2000 */
SELECT MAX(a)
FROM
(
SELECT COUNT(EmployeeID) AS a FROM HumanResources.Employee GROUP BY YEAR(BirthDate)
) AS a

/**//* SQL server 2005 */
SELECT MAX(a)
FROM
(
SELECT
    ROW_NUMBER() OVER(PARTITION BY YEAR(BirthDate) ORDER BY BirthDate) AS a
FROM HumanResources.Employee
) AS a

-- 出生日期涵盖了多少年
/**//* SQL server 2000 */
SELECT COUNT(DISTINCT YEAR(BirthDate)) FROM HumanResources.Employee

/**//* SQL server 2005 */
SELECT MAX(a)
FROM
(
SELECT
    DENSE_RANK() OVER(ORDER BY YEAR(BirthDate)) AS a
FROM HumanResources.Employee
) AS a

-- 显示前10%的数据
/**//* SQL server 2000 */
SELECT TOP 10 Percent BirthDate FROM HumanResources.Employee

/**//* SQL server 2005 */
SELECT
    BirthDate
FROM
(
SELECT
    NTILE(10) OVER(ORDER BY BirthDate DESC) AS a,BirthDate
FROM HumanResources.Employee
) AS a
WHERE a = 1

posted @ 2008-05-26 16:27  宇晨  阅读(291)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3