你真的会玩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吗?查询指定节点及其所有父节 ...
随机推荐
- Qt下HBoxLayout里的按钮有重叠
没想到是一个bug,而且六年了都没有解决: https://bugreports.qt.io/browse/QTBUG-14591 http://stackoverflow.com/questions ...
- 《Programming WPF》翻译 第5章 6.触发器
原文:<Programming WPF>翻译 第5章 6.触发器 目前为止,我们已经看到样式,作为一个Setter元素的集合.当应用一个样式时,在Setter元素中描述的设置不会无条件地应 ...
- PowerShell_零基础自学课程_6_PS中获取帮助信息详解、管道、格式化输
前些文章陆续的说了一些关于这些主题,但是讨论的都不够深入,今天我们深入的了解一下获取帮助信息.管道以及格式化输出的内容. 一.获取帮助信息 在PS中获取帮助信息,最常用的有: -? .get-comm ...
- wikioi1191 数轴染色
题目描述 Description 在一条数轴上有N个点,分别是1-N.一开始所有的点都被染成黑色.接着 我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色.请输出每个操作执行后 剩余黑色点的个 ...
- VMdomainXml
1,One,Euc,Ostack 虚拟磁盘镜像制作方法[Windows,Linux,类linux OS](1,基于ios部署系统生成img,2基于vm xml定义部署系统生成img qcow2) 如需 ...
- 最长公共子串LCS(Longest Common Substring)
一.问题描述 寻求两个字符串中的最大公共字串,其中子串是指字符串中连续的字符组成的,而不是像子序列,按照字符的前后顺序组成.如str1="sgabacbadfgbacst",str ...
- java保留有效数字
DecimalFormat df=DecimalFormat("######0.0") double d = df.format(xx): 保留一位就是"######0. ...
- C#操作IE
操作IE主要使用两个Com Dll: 1.Microsoft Internet Controls 2.Microsoft HTML Object Library 使用Microsoft Interne ...
- Git的一些用法(建立新的branch)
建立新的branch和查看全部的branch(kk的代码是基于现有的branch) 切换到branch kk: 当然我们也能够在android studio里操作: 注意切换的时候代码会丢失,必须先c ...
- Java中随机数生成的两种方法,以及math的floor
1.Math的random方法,调用这个Math.Random()函数能够返回带正号的double值,该值大于等于0.0且小于1.0,即取值范围是[0.0,1.0)的左闭右开区间,返回值是一个伪随机选 ...