Chapter 4 Subqueries

子查询分为:独立子查询(Self-Contained Subqueries)和相关子查询(Correlated Subqueries),独立子查询可以单独拿出来执行,相关子查询可以理解为对外部查询的每一行都执行一遍内部子查询。

EXISTS谓词接受一个子查询,如果子查询能返回任何行,则返回TRUE,否则返回FALSE(注意到了吗?是two-valued logic)。EXISTS后面用SELECT * 没关系,会被优化掉的。

返回前一个或者后一个值的解决方法(思想是用“小于当前值的最大值”表示前一个):

注意以下查询结果中的orderid和prevorderid

SELECT orderid, orderdate, empid, custid,
(SELECT MAX(O2.orderid)
FROM Sales.Orders AS O2
WHERE O2.orderid < O1.orderid) AS prevorderid
FROM Sales.Orders AS O1;

结果:



SQL Server 2012提供了LAG 和LEAD的窗口函数可以达到类似功能。

利用同样的思想,也可以解决连续聚合(连续聚合是一种对累计数据(通常是按照时间顺序)执行的聚合)。例如:返回累计到当前年份的总订货量,举例如下:

SELECT orderyear, qty,
(SELECT SUM(O2.qty)
FROM Sales.OrderTotalsByYear AS O2
WHERE O2.orderyear <= O1.orderyear) AS runqty
FROM Sales.OrderTotalsByYear AS O1
ORDER BY orderyear;

结果:



同样,SQL Server 2012提供了聚合功能的窗口函数。

如果你写了个子查询:

SELECT custid, companyname
FROM Sales.Customers
WHERE custid NOT IN(SELECT O.custid
FROM Sales.Orders AS O);

如果子查询查出来的结果集里面至少有一个NULL的话,那么这个整个查询的结果就是空集。最佳实践是对于IN谓词,在子查询的结果最好不要返回NULL,或者说在子查询里用WHERE O.custid IS NOT NULL来显式过滤掉NULL的行,或者说使用EXIST代替IN:

SELECT custid, companyname
FROM Sales.Customers AS C
WHERE NOT EXISTS
(SELECT *
FROM Sales.Orders AS O
WHERE O.custid = C.custid);

在子查询中,如果在子查询的表中找不到子SELECT的列名,就从外部表里找,所以很可能导致错误,比如Orders表里面其实没有shipper_id这个列,只有shipperid:

SELECT shipper_id, companyname
FROM Sales.MyShippers
WHERE shipper_id IN
(SELECT shipper_id
FROM Sales.Orders
WHERE custid = 43);

这样的话,子查询其实变成了相关子查询,子查询中的shipper_id其实是外部表中的列,导致外部表中的每一行都会被返回。

所以最佳实践是在子查询中为列名加上来源表的别名作为前缀。

《SQL Server 2012 T-SQL基础》读书笔记 - 4.子查询的更多相关文章

  1. SQL Server Window Function 窗体函数读书笔记二 - A Detailed Look at Window Functions

    这一章主要是介绍 窗体中的 Aggregate 函数, Rank 函数, Distribution 函数以及 Offset 函数. Window Aggregate 函数 Window Aggrega ...

  2. SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第1部分)

    为了缩小读取操作所涉及范围,本文首先着眼于简单的SELECT查询,然后引入执行更新操作有关的附加过程.最后你会读到,优化性能时SQLServer使用还原工具的相关术语和流程. 关系和存储引擎 如图所示 ...

  3. SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第2部分)

    计划缓存(Plan Cache) 如果SQL Server已经找到一个好的方式去执行一段代码时,应该把它作为随后的请求重用,因为生成执行计划是耗费时间且资源密集的,这样做是有有意义的. 如果没找到被缓 ...

  4. SQL Sever 各版本下载 SQL Server 2012下载SQL Server 2008下载SQL Server 2005

    SQL Server 2012SQL Server 2012 开发版(DVD)(X64,X86)(中文简体)ed2k://|file|cn_sql_server_2012_developer_edit ...

  5. sql server 2012 导出sql文件

    导出表数据和表结构sql文件 在工作中,经常需要导出某个数据库中,某些表数据:或者,需要对某个表的结构,数据进行修改的时候,就需要在数据库中导出表的sql结构,包括该表的建表语句和数据存储语句!在这个 ...

  6. SQL Server Window Function 窗体函数读书笔记一 - SQL Windowing

    SQL Server 窗体函数主要用来处理由 OVER 子句定义的行集, 主要用来分析和处理 Running totals Moving averages Gaps and islands 先看一个简 ...

  7. SQL Server 2012:SQL Server体系结构——一个查询的生命周期(第3部分)(完结)

    一个简单的更新查询 现在应该知道只读取数据的查询生命周期,下一步来认定当你需要更新数据时会发生什么.这个部分通过看一个简单的UPDATE查询,修改刚才例子里读取的数据,来回答. 庆幸的是,直到存取方法 ...

  8. SQL Server 2012 - 动态SQL查询

    动态SQL的两种执行方式:EXEC @sql 和 EXEC sys.sp_executesql @sql DECLARE @c_ids VARCHAR(200) SET @c_ids ='1,2' - ...

  9. 在SQL Server中为什么不建议使用Not In子查询

        在SQL Server中,子查询可以分为相关子查询和无关子查询,对于无关子查询来说,Not In子句比较常见,但Not In潜在会带来下面两种问题: 结果不准确 查询性能低下       下面 ...

随机推荐

  1. [转帖]JVM内存结构 VS Java内存模型 VS Java对象模型

    JVM内存结构 VS Java内存模型 VS Java对象模型 https://www.hollischuang.com/archives/2509 Java作为一种面向对象的,跨平台语言,其对象.内 ...

  2. 获取客户机MAC地址 根据IP地址 获取机器的MAC地址 / 获取真实Ip地址

    [DllImport("Iphlpapi.dll")] private static extern int SendARP(Int32 dest, Int32 host, ref ...

  3. 【Python】循环结构中的else

    else在循环结构中,只有循环正常结束后才执行else,如果使用break跳出了循环,不会执行else for i in range(0,10): print(i)else: print(" ...

  4. PHP 经典有趣的算法

    原文:https://blog.csdn.net/a519395243/article/details/77942913 1.一群猴子排成一圈,按1,2,…,n依次编号.然后从第1只开始数,数到第m只 ...

  5. hdu6468 zyb的面试 (思维)

    题目传送门 题意: 将1~n个数按字典序排序后,求第k个数 思路: 代码: #include<stdio.h> #include<iostream> #include<a ...

  6. offsetWidth clientWidth scrollWidth 的区别

    了解 offsetWidth clientWidth scrollWidth 的区别 最近需要清除区分开元素的width,height及相应的坐标等,当前这篇用来区分offsetWidth clien ...

  7. Linux安装 jdk&maven

    JDK安装 1. 下载JDK压缩包http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...

  8. 7.css3表格、列表、边框的样式设置--list/border

    1.css表格: ①Border-collapse是否把表格边框合并为单一的边框.Separate默认值,collapse合并. ②Border-spacing分割单元格边框的距离. ③Caption ...

  9. DOMContentLoaded和load的区别

    一.概念 DOMContentLoaded 当初始的 HTML 文档被完全加载和解析完成之后,DOMContentLoaded 事件被触发,而无需等待样式表.图像和子框架的完成加载. load loa ...

  10. background的水平条纹和斜向条纹

    水平条纹: <div id="div1"> </div> linear-gradient属性 #div1{ width: 100px; height: 10 ...