博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
你真的会玩SQL吗?冷落的Top和Apply
阅读量:6076 次
发布时间:2019-06-20

本文共 3493 字,大约阅读时间需要 11 分钟。

你真的会玩SQL吗?系列目录

 

本章预先想写一些Top和Apply基本的用法,但好像没什么意义,所以删掉了一些无用的东西,只留下几个示例,以保证系列的完整性。

Top和Apply解决的常见问题,如返回每个雇员的3个最新订单,订单的时间越新优先级就越高,但还需要引入一个决胜属性,以确定时间桢的订单的优先级,如可用id作为决胜属性。这里提供的解决方案比其它方案要简单得多,且执行速度更快。

返回每个雇员的3个最新订单:

SELECT  empid ,        orderid ,        custid ,        orderdate ,        requireddateFROM    sales.orders AS o1WHERE   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.requireddateFROM    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 ,        requireddateFROM    ( SELECT    orderid ,                    custid ,                    orderdate ,                    requireddate ,                    ROW_NUMBER() OVER ( PARTITION BY empid ORDER BY orderdate DESC , orderid DESC ) AS rownum          FROM      sales.orders        ) AS dWHERE   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',89insert @student select '一班' ,'A002','A2',89insert @student select '一班' ,'A003','A3',59insert @student select '一班' ,'A004','A4',80insert @student select '一班' ,'A005','A5',99insert @student select '一班' ,'A006','A6',100insert @student select '一班' ,'A007','A7',82 insert @student select '二班' ,'B001','B1',19insert @student select '二班' ,'B001','B2',81insert @student select '二班' ,'B001','B3',69insert @student select '二班' ,'B001','B4',86insert @student select '二班' ,'B001','B5',88insert @student select '二班' ,'B001','B6',99insert @student select '二班' ,'B001','B7',100insert @student select '二班' ,'B001','B8',90insert @student select '二班' ,'B001','B9',97   insert @tj select '一班',3insert @tj select '二班',5

 参考SQL:

-- 2005.T-SQL select t.bj,s.xh,s.name,s.cjfrom @tj tcross 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 )sorder by case when t.bj='一班' then 1 else 2 end asc,s.cj desc,s.xh asc    ---排序

 

转载地址:http://hzsgx.baihongyu.com/

你可能感兴趣的文章
面试官问你“有什么问题问我吗?”,你该如何回答?
查看>>
这么好的平台,居然荒废了这么久没使用,以后要常来!
查看>>
Rails
查看>>
Lightning学習資料
查看>>
字节流与字符流的区别详解
查看>>
js数组去重的4个方法
查看>>
Floyd判圈算法
查看>>
hdu 4965 矩阵快速幂 矩阵相乘性质
查看>>
iOS - App 应用
查看>>
用户登录验证
查看>>
TSVNCache.exe严重占用CPU问题
查看>>
详细易懂的解释变量和指针变量重新赋值的过程和问题
查看>>
Python 操作 MYSQL
查看>>
关于解决javaEE端口占用的方法
查看>>
mysql 更改表名称
查看>>
handlerbars入门学习
查看>>
关于“VS2010语法检查红线不见了”的解决方案
查看>>
C++模板使用介绍
查看>>
Object-C中 - self 和super 的含义
查看>>
Optimizing graphics performance
查看>>