Chinaunix首页 | 论坛 | 博客
  • 博客访问: 287729
  • 博文数量: 163
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: -40
  • 用 户 组: 普通用户
  • 注册时间: 2017-03-08 00:28
文章分类

全部博文(163)

文章存档

2015年(2)

2014年(35)

2013年(28)

2012年(30)

2011年(22)

2010年(14)

2009年(8)

2008年(13)

2007年(11)

分类: SQLServer

2014-01-02 14:55:31

--CREATE TABLE Students
--(
--    ClassID int,
--    StuName char(10),
--    Achi int
--);

--INSERT INTO Students
--VALUES(1, '张山', 100),
--      (1, '李明', 90),
--      (1, '王磊', 95),
--      (2, '孙科', 100),
--      (2, '赵强', 80),
--      (2, '王智', 90),
--      (3, '李海', 95);

--1.使用联接获取前几行
--如果将Students表打开两次,将一个考生与其大于或等于自己成绩的考生联接,
--我们看看会得到什么样的结果。参考下面的语句
SELECT S1.*, S2.*
FROM Students AS S1
INNER JOIN Students AS S2
  ON S1.ClassID = S2.ClassID AND S2.Achi >= S1.Achi
ORDER BY S1.ClassID, S1.Achi DESC;

--从上表中可以看出,1班中的第1名张山有1条记录,第2名王磊有2条记录,第3名有3条记录。

--获取每班中前2名的考生
SELECT S1.ClassID, S1.Achi, MAX(S1.StuName) AS StuName
FROM Students AS S1
INNER JOIN Students AS S2
  ON S1.ClassID = S2.ClassID AND S2.Achi >= S1.Achi
GROUP BY S1.ClassID, S1.Achi 
HAVING COUNT(*) <=2
ORDER BY S1.ClassID, S1.Achi DESC;

--使用窗口排名函数获取前几行
--窗口计算是从SQLServer 2005开始提供的新技术,
--每一组数据被称为一个窗口,
--RANK( )和DENSE_RANK( )函数都可以按窗口进行排名计算
--Rank()        排名名次间会存在间隔
--DENSE_Rank()  密集排名,名次之间不会有间隔
SELECT ClassID
     , StuName
     , Achi
     , RANK() OVER(PARTITION BY ClassID ORDER BY Achi DESC) AS rank_r
     , DENSE_RANK() OVER(PARTITION BY ClassID ORDER BY Achi DESC) AS rank_rn
FROM Students;

--每班取前两名
WITH StuRank(ClassID, StuName, Achi, rank_rn)AS(
SELECT ClassID
     , StuName
     , Achi
     , DENSE_RANK() OVER(PARTITION BY ClassID ORDER BY Achi DESC) rank_rn
FROM Students
)SELECT * FROM StuRank WHERE rank_rn <= 2;

也可以直接使用子查询实现上面的CTE的功能.

原文链接:
参考链接:

阅读(1257) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~