目录

关联查询

例子

分解相关的嵌套查询

与不同的表一起使用

关联子查询与内部联接

哪个更快?

哪个更容易阅读?

哪一个更好?

HAVING子句中的关联子查询


在本文中,我们将查看几个示例并将关联子查询与连接进行比较。

关联子查询用于将内部查询的条件与外部查询中的值联系起来。它们是避免“硬编码”值的强大技术。在本文中,查看几个示例并将关联子查询与连接进行比较。

本课的所有示例均基于Microsoft SQL Server Management Studio和AdventureWorks2012数据库。

关联查询

有一些方法可以将外部查询的值合并到子查询的子句中。这些类型的查询称为关联子查询,因为子查询的结果以某种形式连接到外部查询中的值。它们有时称为同步查询。

如果您不知道相关的含义,请查看Google的以下定义:

关联:“具有相互关系或联系,其中一件事影响或依赖于另一件事。” (google)

关联子查询的典型用法是在内部查询的WHERE子句中使用外部查询的列之一。在许多情况下,您希望将内部查询限制为数据子集,这是常识。

例子

我们将提供一个相关的子查询示例,通过报告每个子查询SalesOrderDetail LineTotal,而Average LineTotal代表整体Sales Order。

此请求与我们之前的示例有很大不同,因为我们计算的平均值因每个销售订单而异。

这就是关联子查询发挥作用的地方。我们可以使用外部查询中的值并将其合并到子查询的过滤条件中。

让我们看看我们如何计算平均线总数。为此,我整理了一个插图,显示了带有子查询的SELECT语句。

进一步阐述图表。该SELECT语句由两部分组成,外部查询和子查询。外部查询用于检索所有SalesOrderDetail行。子查询用于查找和汇总特定SalesOrderID的销售订单详细信息行。

如果我要表达我们将要采取的步骤,我会将它们总结为:

  1. 获取SalesOrderID。
  2. 返回所有SalesOrderID匹配SalesOrderDetail项的LineTotal平均值。
  3. 继续到外部查询中的下一个SalesOrderID并重复步骤1和2。

您可以在数据库中运行的AdventureWork2012查询是:

SELECT SalesOrderID,SalesOrderDetailID,LineTotal,(SELECT AVG(LineTotal)FROM   Sales.SalesOrderDetailWHERE  SalesOrderID = SOD.SalesOrderID)AS AverageLineTotal
FROM   Sales.SalesOrderDetail SOD

以下是查询的结果:

有几点需要指出。

  1. 您可以看到我使用列别名来帮助使查询结果更易于阅读。
  2. 我还为外部查询使用了表别名, SOD。这使得在子查询中使用外部查询的值成为可能。否则,查询不相关!
  3. 使用表别名可以明确每个表中的哪些列。

分解相关的嵌套查询

现在让我们尝试使用SQL将其分解。

首先,假设我们将获得我们的示例SalesOrderDetailID 20。对应的SalesOrderID是43661

要获得该项的LineTotal平均值很容易:

SELECT AVG(LineTotal)
FROM   Sales.SalesOrderDetail
WHERE  SalesOrderID = 43661

这将返回值2181.765240。

现在我们有了平均值,我们可以将它插入到我们的查询中:

SELECT SalesOrderID,SalesOrderDetailID,LineTotal,<span style="color: #ff0000;">2181.765240 AS AverageLineTotal
FROM   Sales.SalesOrderDetail
WHERE  SalesOrderDetailID = 20

使用子查询,这变成:

SELECT SalesOrderID,SalesOrderDetailID,LineTotal,(SELECT AVG(LineTotal)FROM Sales.SalesOrderDetailWHERE SalesOrderID = 43661) AS AverageLineTotal
FROM   Sales.SalesOrderDetail
WHERE  SalesOrderDetailID = 20

最后的查询是:

SELECT SalesOrderID,SalesOrderDetailID,LineTotal,(SELECT AVG(LineTotal)FROM Sales.SalesOrderDetail
WHERE  SalesOrderID = SOD.SalesOrderID) AS AverageLineTotal
FROM   Sales.SalesOrderDetail AS SOD

与不同的表一起使用

关联子查询,或者就此而言,任何子查询,可以使用与外部查询不同的表。当您使用“父”表时,这可能会派上用场,例如SalesOrderHeader,并且您希望在结果中包含子行的摘要,例如来自SalesOrderDetail。

让我们返回销售订单明细行的OrderDate、TotalDue和数量。为此,我们可以使用下图来了解我们的方位:

为此,我们将在SELECT语句中包含一个关联子查询以返回SalesOrderDetail行数的COUNT。我们将通过过滤外部查询的SalesOrderID来确保计算正确的SalesOrderDetail项。

这是最后的SELECT声明:

SELECT SalesOrderID,OrderDate,TotalDue,(SELECT COUNT(SalesOrderDetailID)FROM Sales.SalesOrderDetailWHERE SalesOrderID = SO.SalesOrderID) as LineCount
FROM   Sales.SalesOrderHeader SO

结果是:

此示例需要注意的一些事项是:

  • 子查询从与外部查询不同的表中选择数据。
  • 我使用表和列别名来更容易阅读SQL和结果。
  • 请务必仔细检查您的where子句!如果您忘记在子查询WHERE子句中包含表名或别名,则不会关联查询。

关联子查询与内部联接

重要的是要了解您可以使用子查询或联接获得相同的结果。尽管两者都返回相同的结果,但每种方法都有优点和缺点!

考虑最后一个例子,我们为SalesHeader项计算项的行。

SELECT SalesOrderID,OrderDate,TotalDue,(SELECT COUNT(SalesOrderDetailID)FROM Sales.SalesOrderDetail
WHERE SalesOrderID = SO.SalesOrderID) as LineCount
FROM  Sales.SalesOrderHeader SO

可以使用INNER JOIN和GROUP BY来完成相同的查询:

SELECT   SO.SalesOrderID,OrderDate,TotalDue,COUNT(SOD.SalesOrderDetailID) as LineCount
FROM     Sales.SalesOrderHeader SOINNER JOIN Sales.SalesOrderDetail SODON SOD.SalesOrderID = SO.SalesOrderID
GROUP BY SO.SalesOrderID, OrderDate, TotalDue

哪个更快?

您会发现许多人会说要避免子查询,因为它们速度较慢。他们会争辩说,关联子查询必须为外部查询中返回的每一行“执行”一次,而INNER JOIN唯一的子查询必须通过数据。

我呢?我说检查查询计划。我对上面的两个例子都遵循了自己的建议,发现计划是一样的!

这并不是说如果有更多数据,计划就会改变,但我的观点是你不应该只是做出假设。大多数SQL DBMS优化器都非常擅长找出执行查询的最佳方法。他们将采用您的语法,例如子查询或INNER JOIN,并使用它们来创建实际的执行计划。

哪个更容易阅读?

根据您的习惯,您可能会发现该INNER JOIN示例比关联查询更易于阅读。就个人而言,在这个例子中,我喜欢关联子查询,因为它看起来更直接。我更容易看到正在计算的内容。

在我看来,INNER JOIN是不那么直接的。首先,您必须看到所有销售明细行都被返回然后汇总。在您阅读整个声明之前,您不会真正明白这一点。

哪一个更好?

让我知道你的想法。我想听听您是否更愿意使用关联子查询或INNER JOIN示例。

HAVING子句中的关联子查询

与任何其他子查询一样,HAVING子句中的子查询可以与外部查询中的字段相关联。

假设我们进一步按婚姻状况对职位进行分组,并且只想保留那些休假时间大于相应整体婚姻状况的职位和军人身份的组合?

换句话说,我们想回答一个类似于“已婚会计师的平均剩余假期是否比一般已婚员工多?”的问题?

找出答案的一种方法是使用以下查询:

SELECT   JobTitle,MaritalStatus,AVG(VacationHours)
FROM     HumanResources.Employee AS E
GROUP BY JobTitle, MaritalStatus
HAVING   AVG(VacationHours) > (SELECT AVG(VacationHours)FROM   HumanResources.EmployeeWHERE  HumanResources.Employee. MaritalStatus =E.MaritalStatus)

有几点需要指出。首先,请注意我在外部查询中将其Employee别名为“E”。这允许我在内部查询中引用外部表。

此外,对于关联查询,只有在GROUP BY中使用的字段才能在内部查询中使用。例如,对于kicks和grins,我尝试替换MaritalStatus为Gender并得到一个错误。

SELECT   JobTitle,MaritalStatus,AVG(VacationHours)
FROM     HumanResources.Employee AS E
GROUP BY JobTitle, MaritalStatus
HAVING   AVG(VacationHours) > (SELECT AVG(VacationHours)FROM   HumanResources.EmployeeWHERE  HumanResources.Employee. Gender = E. Gender)

是一个损坏的查询。如果您尝试运行它,您将收到以下错误:

Column ‘HumanResources.Employee.Gender’ is invalid in the HAVING clause
because it is not contained in either an aggregate function or the GROUP BY clause.

本文最初发布于Correlated Subqueries in SQL - Essential SQL

https://www.codeproject.com/Articles/5326767/Correlated-Subqueries-in-SQL

SQL中的关联子查询相关推荐

  1. SQL进阶之关联子查询练习

    SQL进阶之关联子查询 一.关联子查询简介 二.关联子查询实操 1.CreateTable 2.Sample 一.关联子查询简介 通过关联表内部条件从而达到查询效果 二.关联子查询实操 注:版本使用: ...

  2. SQL进阶之关联子查询行间比较

    SQL进阶之关联子查询行间比较 关联子查询行间比较 越前须知(雾) 具体用法 与最近一年比较营收 移动平均值和移动累计值 查询重叠的时间区间 关联子查询行间比较 越前须知(雾) 本系列参考<SQ ...

  3. order by 子查询_视图,子查询,标量子查询,关联子查询

    视图 子查询 标量子查询 关联子查询 如何用SQL解决业务问题 各种函数 1. 视图 视图内存放SQL查询语句,运行时运行该语句.查出的数据为临时数据 创建视图 create view as 视图名称 ...

  4. python中and与or的执行顺序-关联子查询的执行顺序是什么

    sql的编写顺序 select .. from .. where .. group by ..having .. order by .. sql的执行顺序 from .. where .. group ...

  5. server多笔记录拼接字符串 sql_第四章、SQL Server数据库查询大全(单表查询、多表连接查询、嵌套查询、关联子查询、拼sql字符串的查询、交叉查询)...

    4.1.查询的类型 declare @value as int set @value = 50 select  'age:'as age,2008 years,@valueas va --这种查询时跟 ...

  6. SQL子查询和关联子查询

    子查询:将用来定义视图的SELECT语句直接用于FROM子句中. SELECT <列名1>, <列名2>, - FROM (<SELECT语句>) AS <视 ...

  7. Oracle 的关联子查询(correlated subquery) 简介.

    相信 接触过 ocp考题既, 都会见到 correlated subquery的字眼. correlated subquery的中文名称就是相关子查询呢? 1. 什么是子查询 这个很简单,  子查询就 ...

  8. Oracle 数据库的子查询(关联子查询)

    文章目录 一.子查询结果返回一个值(单列单行) 二.子查询结果返回多行(单列多行) 三.子查询结果返回多列多行 四.关联子查询 (一)子查询执行顺序 (二)exists 关键字 五.子查询总结 六.关 ...

  9. mysql 子查询执行顺序_关联子查询的执行顺序是什么

    sql的编写顺序 select .. from .. where .. group by ..having .. order by .. sql的执行顺序 from .. where .. group ...

最新文章

  1. 查询表中的所有字段名
  2. java pathinfo,nginx下支持PATH_INFO的方法实例详解
  3. OpenResty 通过二级域名做跳转
  4. python中self_一篇文章让你彻底搞清楚Python中self的含义
  5. [我的1024开源程序]60元写的宠物网页和音乐网页
  6. Delphi 7.0常用函数速查手册
  7. Base64加解密的实现方式
  8. ubuntu 在vm中如何上网及注意问题
  9. 新年计划书...2012-01-01
  10. CSS基础——CSS复合选择器【学习笔记】
  11. hdu 1333水题
  12. SSL/TLS的X.509证书
  13. more than one device and emulator
  14. 使用OpenCV进行图片模糊处理(归一化滤波器)
  15. 三国英杰之赵云传java7723_幻世三国之赵云传奇
  16. 计算机办公模式是什么,华为Mate 10“电脑模式”告诉你什么是真正的“移动办公”...
  17. 问题 G: 奇数阶幻方
  18. 微软客服的痛苦-还敢应聘微软客服
  19. 大厂“P8/P9”必读《成为思维高手》pdf 电子书下载
  20. java设置窗体不透明的函数_透明窗口(窗口上面文字图片等内容不透明)的实现(使用SetLayeredWindowAttributes API函数)...

热门文章

  1. 批量识别医疗票据【第2版】
  2. bootanimation文件名_如何自己制作安卓手机开机动画打造你的个性
  3. ERP - ERP项目实施考核办法
  4. t20天正结构v7.0破姐 安装教程
  5. 10M/S!百度网盘偷偷更新,终于实现免费不限速了!
  6. 长链接转短链接的一次尝试
  7. ATECC508A/ATECC608A加密芯片国产替代
  8. js 拖动--动态改变div的宽高大小
  9. Java作业 折扣计算
  10. erlang nif 中文手册