T-SQL的进阶:超越基本级别3:构建相关子查询

格雷戈里·拉森,2014/03/05

原文链接:

http://www.sqlservercentral.com/articles/Stairway+Series/105972/

该系列

这篇文章是进阶系列的一部分: t - sql的进阶:超越基础

从他的阶梯到T-SQL DML,Gregory Larsen涵盖了T-SQL语言的更高级的方面,如子查询。

在这个楼梯的第二层,我讨论了如何在Transact - T-SQL语句中使用子查询。这个楼梯级别将通过讨论一种称为关联子查询的子查询类型来扩展子查询主题。我将探讨什么是相关子查询,以及它与普通子查询的区别。此外,我还将为您提供一些超越基础的Transaction- T-SQL语句示例,并使用关联子查询来帮助识别结果集中返回的行,以满足复杂的业务需求。

什么是相关子查询?

在这个楼梯的第2级,我们了解到正常的子查询只是在另一个Transact - SQL语句内的一个SELECT语句,在这个语句中子查询如果独立于外部查询而返回结果。关联子查询是子查询的一种形式,它不能独立于外部查询运行,因为它包含来自外部查询的一个或多个列。相关子查询,就像普通的子查询,有时被称为内部查询。如果相关子查询(内部查询)独立于外部查询运行,则它将返回一个错误。因为内部查询的执行依赖于来自外部查询的值,因此它被称为相关子查询。

相关子查询可以执行很多次。它将为在外部查询中选择的每个候选行运行一次。每个候选行的列值将用于为关联子查询的每次执行的内部的外部查询列提供值。包含相关子查询的语句的最终结果将基于相关子查询的每次执行的结果。

相关子查询示例的示例数据

为了演示如何使用相关子查询,我需要一些测试数据。我的所有示例都将使用AdventureWorks2008R2数据库,而不是创建自己的测试数据。如果你想跟随并运行在您的环境中我的例子你可以从这里下载AdventureWorks2008R2数据库:http://msftdbprodsamples.codeplex.com/releases/view/93587

WHERE子句中关联子查询的示例

为了演示在WHERE子句中使用关联子查询,我想要确定这些CustomerID在单个订单中购买了超过70个项目。为了达到这个要求,我可以运行清单1中的代码。

清单1:在WHERE子句中关联子查询

当我运行清单1中的代码时,我得到了报告1中的输出。

报告1:运行清单1中的代码时返回的结果

如果您回顾清单1中的代码,您将看到我使用相关子查询限制了我的位置。子查询是圆括号中的代码,我从清单1中提取了相关的子查询代码,并将其放入清单2中。

清单2:清单1中的子查询代码

如果我运行清单2中的代码,我将发现在报告2中显示了一个错误。

报告2:在清单2中运行代码时出错

我得到了报告2中显示的错误,因为关联子查询包含对列的引用。SalesOrderID,它是来自外部查询的一列。由于所有相关子查询从外部查询引用一个或多个列,因此不能独立地运行与它关联的外部查询。不能独立于整个Transact - SQL语句运行子查询的事实是将相关子查询与普通子查询区分开来。

这里给出的示例是在WHERE子句中使用相关子查询的一个非常简单的例子。希望通过这样一个简单的示例,它很容易理解普通子查询和相关子查询之间的区别。通常,一个相关的子查询可能要复杂得多。此外,请记住,在不使用相关子查询的情况下,可能还有其他方法来满足您的业务需求。

正如您所看到的,编写一个相关子查询非常类似于普通子查询,但是您不能独立地运行相关子查询。

HAVING子句中关联子查询的示例

有时,您可能想要从外部查询中限制一个有不同值的子句。这时,您可以在您的“有”子句中使用相关子查询。假设您必须编写一个查询,该查询将计算那些在2008年税前购买价值超过15万美元的产品的客户的回扣金额。清单3中的代码通过在HAVING子句中使用关联子查询来计算这些值客户的回扣金额。

清单3:有子句的相关子查询

当我运行清单5中的代码时,我得到了报告3中的结果。

报告3:运行清单3的结果

清单3中的相关子查询代码在关联子查询中的外部查询中使用GROUP BY子句中的CustomerID。关联子查询将对从GROUP BY子句返回的每一行执行一次。这允许“有”子句通过对每个SalesOrderHeader记录的SubTotal列的值求和来计算销售给每个CustomerID的产品总量,其中记录与来自外部查询的CustomerID相关联。清单3中的transact - sql语句只返回了CustomerID已经购买超过15万美元的产品的一行。

包含相关子查询的UPDATE语句的示例

相关子查询不仅可以使用SELECT语句返回结果集。您还可以使用它们来更新SQL Server表中的数据。为了演示这一点,我首先使用清单4中的代码在tempdb表中生成一些测试数据。

清单4:创建和填充测试表的代码

清单4中的代码创建了一个CarInventory表,然后填充了8行,表示当前库存的汽车。

销售经理周期性地使用清单5中的查询来查看他的InvoicePriceRatio。

清单5:InvoicePriceRatio查询

当经理运行此查询时,她注意到有许多类似的汽车,其发票金额相同,有不同的InvoicePriceRatio值。为了最大限度地提高她的发票价格,她要求她支持编写一个查询,以更新她所有汽车上的StickerPrice,这样每辆车都有相同的CarName值,就有相同的InvoicePriceRatio。她希望IT人员将StickerPrice设置为与CarName的最大价格相同的值。这样,所有具有相同CarName值的汽车将具有相同的StickerPrice值。为了完成CarInventory表的更新,IT人员运行清单6中的Transact - SQLl语句,其中包含一个相关子查询。

清单6:相关子查询,以更新CarInventory以最大价格

清单8中的代码使用关联子查询中的外部查询的CarName来标识每个惟一的CarName的最大StickerPrice。然后,在相关子查询中发现的最大StickerPrice值用于更新具有相同名称的每个CarInventory记录的StickerPrice值。

相关子查询的性能考虑

在编写包含相关子查询的Transact - SQL语句时,应该注意一些性能方面的考虑。当外部查询包含少量行时,性能并不差。但是,当外部查询包含大量的行时,从性能的角度来看,它的伸缩性并不好。这是因为要对外部查询中的每个候选行执行相关的子查询。因此,当外部查询包含越来越多的候选行时,一个相关的子查询必须多次执行,因此Transact - SQL语句将需要更长的时间运行。如果您发现相关子查询Transact - SQL语句的性能不符合您的要求,那么您应该寻找替代解决方案,例如使用内部或外部连接操作的查询,或者从外部查询返回少量候选行的查询。

摘要

关联子查询是一个内部查询,它包含来自外部查询的一个或多个列。关联子查询对外部查询的每个候选行执行一次。因为关联子查询包含来自外部查询的列,因此它不能独立于外部查询运行。相关子查询有它们的位置,尽管在外部查询中识别出大量候选行时,从性能角度看,它们的伸缩性并不好。

问题和答案

在本节中,您可以通过回答以下问题来回顾您如何理解相关子查询的概念。

问题1:

在编写相关子查询时,需要有___________________。(填入空白)

来自内部查询的一个或多个列,用于约束相关子查询的结果。

在相关子查询的选择列表中使用的内部查询中的一个或多个列。

来自外部查询的一个或多个列,用于约束相关子查询的结果。

在相关子查询的选择列表中使用的外部查询的一个或多个列。

问题2:

选择所有关于相关子查询的语句。

随着候选行的数量增加,包含相关子查询的Transact - SQL语句的性能得到了提高。

相关子查询将对来自外部查询的每个候选行执行一次。

相关子查询将引用内部查询中的一个或多个列。

当在一个拥有子句中使用相关子查询时,将对由GROUP by子句返回的每个候选行执行一次内部查询。

问题3:

相关子查询与普通子查询类似,而相关子查询可以独立于整个Transact - SQL语句(True或False)运行。

真正的

答案:

问题1:

正确答案是c .相关子查询需要在相关子查询语句中使用外部查询中的一个或多个列。在执行相关子查询时,这些外部列引用将替换为每个候选行的值。

问题2:

正确的答案是b和d . a是不正确的,因为随着候选行数量的增加,相关子查询的执行次数增加,而Transact - SQL语句性能变得更糟。c是不正确的,因为相关子查询必须包含来自外部查询的一个或多个行,而不是内部查询。

问题3:

正确的答案是b .如果您尝试独立于完整的Transact - SQL语句运行相关子查询,那么相关的子查询语句将会失败。

这篇文章是T - SQL的进阶的一部分:除了基本的楼梯

注册到我们的RSS频道,一旦我们在楼梯上发布一个新的级别,就会得到通知!

T-SQL的进阶:超越基本级别3:构建相关子查询——701小组的更多相关文章

  1. [SQL SERVER系列]之嵌套子查询和相关子查询

    子查询有两种类型,一种是只返回一个单值的子查询,这时它可以用在一个单值可以使用的地方,这时子查询可以看作是一个拥有返回值的函数:另外一种是返回一列值的子查询,这时子查询可以看作是一个在内存中临时存在的 ...

  2. sql之独立子查询和相关子查询总结

    1.独立子查询:顾名思义:就是子查询和外层查询不存在任何联系,是独立于外层查询的: 下面就看一个例子: 有一张订单表 Sales.Order 和一张 客户表 Sales.Customer 下面的sql ...

  3. SQL相关子查询是什么?和嵌套子查询有什么区别?

    目录 两者的各种叫法 相关子查询MySQL解释 相关子查询Wikipedia解释 相关子查询执行步骤拆解 相关子查询和嵌套查询的区别 参考资料 两者的各种叫法 相关子查询叫做:Correlated S ...

  4. 相关子查询【SQL Server】

    查询book表中大于该类图书价格平均值的图书信息 先将第一条记录的类编号的值为2代入子查询中,子查询为 select avg(price) from book b where b.id=2 则得到类编 ...

  5. sql 相关子查询

    子查询:嵌套在其他查询中的查询. 子查询有称内部查询,而包含子查询的语句称之为外部查询 所有的子查询可以分两类,既 相关子查询和非相关子查询 1>非相关子查询是独立于外部查询的子查询,子查询总共 ...

  6. 相关子查询和嵌套子查询 [SQL Server]

    SQLServer子查询可以分为 相关子查询 和 嵌套子查询 两类.前提,假设Books表如下: 类编号  图书名         出版社               价格-------------- ...

  7. SQL嵌套子查询和相关子查询的执行过程有什么区别(推荐)

    SQLServer子查询可以分为 相关子查询 和 嵌套子查询 两类.前提, 假设Books表如下: 类编号 图书名 出版社 价格 ----------------------------------- ...

  8. 2.SQL语言进阶

    0.实验数据 表1.course表 表2.student表 表3.sc表 1.SQL连接 内连接 select * from student,sc where student.sno=sc.sno;/ ...

  9. SQL Server进阶 窗口函数

    概述  设计窗口函数目的? 在开窗函数出现之前存在着很多用 SQL 语句很难解决的问题,很多都要通过复杂的相关子查询或者存储过程来完成. 为了解决这些问题,在 2003 年 ISO SQL 标准加入了 ...

随机推荐

  1. python爬虫之爬取百度图片

    ##author:wuhao##爬取指定页码的图片,如果需要爬取某一类的所有图片,整体框架不变,但需要另作分析#import urllib.requestimport urllib.parseimpo ...

  2. mysql在cmd命令下执行数据库操作

    windows+r 运行cmd命令,执行以下操作! 当mysql 数据库文件相对于来说比较大的时候,这个时候你可能在正常环境下的mysql中是导入不进去的,因为mysql数据库本身就有默认的导入文件大 ...

  3. 我的第一个python web开发框架(9)——目录与配置说明

    和老大聊完后,小白回家接收到相关工具函数包后,就按要求开始干活,首先要做的是熟悉配置参数和了解工具函数有哪些实用的工具. 由于这个项目比较简单,所以不用创建那么多分类,只需要api.common.co ...

  4. win10 uwp 验证输入 自定义用户控件

    TextBox是给用户输入,我们有时要用户只输入数字,而用户输入汉字,我们就有提示用户,那么这东西用到次数很多,我们需要做成一个控件. 我们可以用别人的库,我找到一个大神写的库,很好用 我们使用这个库 ...

  5. STM32外部中断线编程

    #include "ExtiConfig.h" unsigned char key1Down = 0; unsigned char key2Down = 0; /********* ...

  6. 正六边形网格化(Hexagonal Grids)原理与实现

    在路径规划.游戏设计栅格法应用中,正六边形网格不如矩形网格直接和常见,但是正六边形具有自身的应用特点,更适用于一些特殊场景中,比如旷阔的海洋.区域或者太空.本文主要讲述如何对正六边形进行几何学分析.网 ...

  7. Java8之旅(六) -- 使用lambda实现尾递归

    前言 本篇介绍的不是什么新知识,而是对前面讲解的一些知识的综合运用.众所周知,递归是解决复杂问题的一个很有效的方式,也是函数式语言的核心,在一些函数式语言中,是没有迭代与while这种概念的,因为此类 ...

  8. Azure环境中Nginx高可用性和部署架构设计

    前几篇文章介绍了Nginx的应用.动态路由.配置.在实际生产环境部署时,我们需要同时考虑Nginx的高可用性和部署架构. Nginx自身不支持集群以保证自身的高可用性,商业版本的Nginx+推荐: T ...

  9. Spring框架学习之依赖注入

    Spring框架从2004年发布的第一个版本以来,如今已经迭代到5.x,逐渐成为JavaEE开发中必不可少的框架之一,也有人称它为Java下的第一开源平台.单从Spring的本身来说,它贯穿着整个表现 ...

  10. 最长回文子串---Manacher算法

    百度:Manacher算法 代码 #include <iostream> #include <string> #include <cstring> #include ...