你真的会玩SQL吗?Top和Apply
本章预先想写一些Top和Apply基本的用法,但好像没什么意义,所以删掉了一些无用的东西,只留下几个示例,以保证系列的完整性。
Top和Apply解决的常见问题,如返回每个雇员的3个最新订单,订单的时间越新优先级就越高,但还需要引入一个决胜属性,以确定时间桢的订单的优先级,如可用id作为决胜属性。这里提供的解决方案比其它方案要简单得多,且执行速度更快。
返回每个雇员的3个最新订单:
SELECT empid ,
orderid ,
custid ,
orderdate ,
requireddate
FROM sales.orders AS o1
WHERE orderid IN ( SELECT TOP 3
orderid
FROM sales.orders AS o2
WHERE o2.empid = o1.empid
ORDER BY orderdate DESC ,
orderid DESC )
运用APPLY解决:
SELECT e.empid ,
a.orderid ,
a.custid ,
a.orderdate ,
a.requireddate
FROM hr.employees AS e
CROSS APPLY ( SELECT TOP 3
orderid ,
custid ,
orderdate ,
requireddate
FROM sales.orders AS o
WHERE o.empid = e.empid
ORDER BY orderdate DESC ,
orderid DESC
) AS a
先扫描employees 获得empid,对每个empid值对orders表查询返回 该雇员的3个最新订单。这里可以返回多个属性。
还有一种解决方案在特定情况下竟然比使用APPLY运算符的方法还要快,使用ROW_NUMBER函数。先为每个订单计算行号,按empid进行分区,并按orderdate desc, orderid desc 顺序排序。然后在外部查询中,只筛选行号小于或等于3的行。
如下:
SELECT orderid ,
custid ,
orderdate ,
requireddate
FROM ( SELECT orderid ,
custid ,
orderdate ,
requireddate ,
ROW_NUMBER() OVER ( PARTITION BY empid ORDER BY orderdate DESC , orderid DESC ) AS rownum
FROM sales.orders
) AS d
WHERE rownum <= 3
练习:
从学生表中选取对应班级的前num名学生成绩
--显示结果
/*
bj xh name cj
---------- ---- ---------- -----------
一班 A006 A6 100
一班 A005 A5 99
一班 A001 A1 89
一班 A002 A2 89 二班 B001 B7 100
二班 B001 B6 99
二班 B001 B9 97
二班 B001 B8 90
二班 B001 B5 88
*/
-- 创建测试表
declare @student table( ---学生表
bj varchar(10), -- 班级
xh char(4), -- 学号
name varchar(10), -- 姓名
cj int) -- 成绩 declare @tj table( ---统计表
bj varchar(10), -- 班级
num int) -- 人数 :从学生表中选取对应班级的前num名学生成绩 set nocount on -- 添加测试数据
insert @student select '一班' ,'A001','A1',89
insert @student select '一班' ,'A002','A2',89
insert @student select '一班' ,'A003','A3',59
insert @student select '一班' ,'A004','A4',80
insert @student select '一班' ,'A005','A5',99
insert @student select '一班' ,'A006','A6',100
insert @student select '一班' ,'A007','A7',82 insert @student select '二班' ,'B001','B1',19
insert @student select '二班' ,'B001','B2',81
insert @student select '二班' ,'B001','B3',69
insert @student select '二班' ,'B001','B4',86
insert @student select '二班' ,'B001','B5',88
insert @student select '二班' ,'B001','B6',99
insert @student select '二班' ,'B001','B7',100
insert @student select '二班' ,'B001','B8',90
insert @student select '二班' ,'B001','B9',97 insert @tj select '一班',3
insert @tj select '二班',5
参考SQL:
-- 2005.T-SQL
select t.bj,s.xh,s.name,s.cj
from @tj t
cross apply (
SELECT TOP(t.num)
with ties -- 加 with ties,一班将选出4个人(2个人并列第三名)
xh,name,cj
from @student
where t.bj=bj -- 加where 功能类似于 inner join ;不加类似于 cross join
order by cj desc
)s
order by case when t.bj='一班' then 1 else 2 end asc,s.cj desc,s.xh asc ---排序
你真的会玩SQL吗?Top和Apply的更多相关文章
- 你真的会玩SQL吗?冷落的Top和Apply
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你真的会玩SQL吗?之逻辑查询处理阶段
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你真的会玩SQL吗?和平大使 内连接、外连接
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你真的会玩SQL吗?三范式、数据完整性
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你真的会玩SQL吗?让人晕头转向的三值逻辑
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你真的会玩SQL吗?EXISTS和IN之间的区别
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你真的会玩SQL吗?无处不在的子查询
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你真的会玩SQL吗?Case也疯狂
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
- 你真的会玩SQL吗?表表达式,排名函数
你真的会玩SQL吗?系列目录 你真的会玩SQL吗?之逻辑查询处理阶段 你真的会玩SQL吗?和平大使 内连接.外连接 你真的会玩SQL吗?三范式.数据完整性 你真的会玩SQL吗?查询指定节点及其所有父节 ...
随机推荐
- python中的继承原则
继承是面向对象的重要特征之一,继承是两个类或者多个类之间的父子关系,子进程继承了父进程的所有公有实例变量和方法.继承实现了代码的重用.重用已经存在的数据和行为,减少代码的重新编写,python在类名 ...
- Qt String 与char* char int之间的转换
下面CSDN的博客已经描述的很好了.不写了 references: http://blog.csdn.net/ei__nino/article/details/7297791 http://blog. ...
- SNMP配置和常用命令OID(转)
博文转至:http://blog.csdn.net/susu09new/article/details/12835191 OID值表示的意义(中文) .1.3.6.1.2.1.1操作系统相关的信息,其 ...
- JAVA大整数傻瓜入门
http://blog.csdn.net/skiffloveblue/article/details/7032290..先记着
- Arm Linux系统调用流程详细解析
Linux系统通过向内核发出系统调用(system call)实现了用户态进程和硬件设备之间的大部分接口. 系统调用是操作系统提供的服务,用户程序通过各种系统调用,来引用内核提供的各种服务,系统调用的 ...
- 五分钟读懂UML类图
平时阅读一些远吗分析类文章或是设计应用架构时没少与UML类图打交道.实际上,UML类图中最常用到的元素五分钟就能掌握,下面赶紧来一起认识一下它吧: 一.类的属性的表示方式 在UML类图中,类使用包含类 ...
- Android将第三方jar打包进apk
转自:http://blog.csdn.net/liushaogeng/article/details/6641704 使用第三方jar包 除了我以下介绍的方法,别的方法我基本上都试验过,均会出现编译 ...
- linux学习方法之二
相信不少想学习linux的新手们正愁不知道看什么linux学习教程好,下面小编给大家收集和整理了几点比较重要的教程,供大家学习,如需想学习更多的话,可到wdlinux学堂寻找更多教程. 安装php扩展 ...
- PHP <<EOF EOF的使用方法
PHP <<EOF EOF的使用方法 <?php $name = '浅水游'; print <<<EOT <html& ...
- Unity 定时开启/关闭外部应用
自从加入工作的队伍里,博客都荒废了,今天周末,难得清静,写篇博客!刚才看到了Process类,随手写了个小demo.给大家分享下! 首先大家要对Process类有一些简单的了解,参考资料:https: ...