翻译:通向T-SQL的阶梯:超越基础水平3:建立相关子查询

原文链接:http://www.sqlservercentral.com/articles/Stairway+Series/105972/   原文作者:Gregory Larsen

该系列

本文是楼梯系列的一部分:通向T-SQL的阶梯:超越基础水平

从他的t - sql DML楼梯后,格雷戈里·拉森涵盖了更高级的子查询等方面的t - sql语言。

在2级楼梯我讨论了如何使用数据库引擎执行子查询的sql语句。 这楼梯水平将扩大在子查询主题讨论类型的子查询称为相关subquery。 我将探索什么是相关子查询,以及它是如何不同于正常的子查询。 另外我将提供你一些Transaction-SQL语句的例子超越基本知识和使用相关子查询来帮助识别行返回的结果集,以满足复杂的业务需求。

相关子查询是什么?

在2级楼梯我们了解到一个正常的子查询只是一个SELECT语句在数据库引擎执行另一个sql语句,子查询可以返回结果,如果独立运行的外部查询。 相关子查询是一种外的子查询,不能独立运行查询,因为它包含一个或多个列从外部查询。 相关子查询,就像一个正常的子查询,有时被称为内部查询。 如果相关子查询(内部查询)独立运行的外部查询将返回一个错误。 因为内部查询的执行取决于价值观从外部查询,它被称为相关子查询

相关子查询可能多次执行。 它将为每个选定的候选人行运行一次外层查询。 每个候选人一行的列值将用于供应值外查询中的列内的每个执行相关子查询。 最后声明,包含一个相关子查询的结果将基于每个执行相关子查询的结果。

样本数据的相关子查询的例子

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

相关子查询的WHERE子句的例子

展示相关子查询的WHERE子句使用假设,我想按顺序确定购买了超过70件的顾客的ID。 完成这个需求我可以运行清单1中的代码。

SELECT CustomerID FROM Sales.SalesOrderHeader OH
WHERE (SELECT COUNT(*) FROM Sales.SalesOrderDetail WHERE SalesOrderID = OH.SalesOrderID) > 70;
清单1:相关子查询的WHERE子句
当我运行清单1中的代码报告1中得到的输出。
CustomerID
-----------
29712
29722
30048
30107

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

如果你检查代码在清单1中您将看到我约束,通过使用相关子查询。 括号内的子查询的代码我已经提取了相关子查询代码与清单1和清单2中把它。

SELECT COUNT(*) FROM Sales.SalesOrderDetail WHERE SalesOrderID = OH.SalesOrderID

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

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

Msg 4104, Level 16, State 1, Line 3
The multi-part identifier "OH.SalesOrderID
" could not be bound.

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

 

我得到报告2所示的错误,因为相关子查询列包含一个引用哦。 SalesOrderID列从外部查询。 因为所有相关子查询引用一个或多个列外查询不能独立地运行它们的外层查询与之相关的。 你不能独立运行子查询整个transact - sql语句的区分在一个正常的子查询相关子查询。

这里给出的例子是一个非常简单的例子在WHERE子句中使用相关子查询。 希望通过这样一个简单的例子是很容易理解的区别正常的子查询和相关子查询。 典型相关子查询可能更加复杂。 此外,记住可能有其他方法来满足您的业务需求不相关子查询。

正如你所看到的写相关子查询非常类似于一个正常的子查询,但你不能独立于外部查询运行相关子查询。

相关子查询的例子HAVING子句

有些时候你可能需要限制条款由外层查询不同的值。 这是当你可以使用子查询相关条款。 假设你要编写一个查询,计算退税金额的客户购买了价值超过150000美元税收在2008年前的产品。 清单3中的代码计算退税金额为那些有价值的客户通过使用相关子查询的条款。

SELECT Outer_H.[CustomerID] , SUM(Outer_H.[SubTotal]) AS TotalPurchase, SUM(Outer_H.[SubTotal]) * .10 AS Rebate
FROM [Sales].[SalesOrderHeader] AS Outer_H 
WHERE YEAR(Outer_H.[OrderDate]) = '2008'
GROUP BY Outer_H.[CustomerID]
HAVING (SELECT SUM(Inner_H.[SubTotal]) FROM [Sales].[SalesOrderHeader] AS Inner_HWHERE Inner_H.[CustomerID] = Outer_H.[CustomerID]AND YEAR(Inner_H.[OrderDate]) = '2008') > 150000
ORDER BY Rebate DESC;

清单3:相关子查询在条款

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

CustomerID  TotalPurchase         Rebate
----------- --------------------- ---------------------------------------
29923       220496.658            22049.665800
29641       210647.4929           21064.749290
29617       187964.844            18796.484400
29913       186387.5613           18638.756130
29818       179916.2877           17991.628770
29940       175358.3954           17535.839540
29987       172169.4612           17216.946120
29736       157700.6034           15770.060340
29995       156984.5148           15698.451480
29770       151824.9944           15182.499440

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

在清单3中使用的相关子查询代码CustomerID外GROUP BY子句的查询相关子查询。 相关子查询会为每一行执行一次返回的GROUP BY子句。 这允许有条款计算每个产品的总量CustomerID从外部查询的值而得到的小计列在每个SalesOrderHeader记录相关的记录CustomerID从外部查询。 清单3中的transact - sql语句,只返回一行CustomerID在购买了超过150000美元的产品。

一个更新语句的例子,其中包含相关子查询

相关子查询不仅可以用于使用SELECT语句返回一个结果集。 您也可以使用它们在SQL服务器更新数据表。 为了证明这一点,我首先会生成一些测试数据下边表,通过使用清单4中的代码

 

USE tempdb;
GO
SET NOCOUNT ON;
CREATE TABLE CarInventory (
ID int identity, 
CarName varchar(50),
VIN varchar(50),
StickerPrice decimal (7,2),
InvoicePrice decimal (7,2));
GO
INSERT INTO CarInventory VALUES ('Explorer','EXP2014123456A',46198.45,38201.87),
('Explorer','EXP2014123493A',47129.98, 38201.87),                               
('Grand Cherokee','JGC20141234345X',41678.45,36201.86),
('Grand Cherokee','JGC20141234556W',44518.31,36201.86),
('Pathfinder','NPF2014987365A',32587.73,28917.10),
('Pathfinder','NPF2014239657B',33577.54,28917.10),
('Pathfinder','NPF2014098587C',35876.12,28917.10),
('Tahoe','TAH201409674A',52001.08,46000.01);

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

清单4中的代码创建了一个CarInventory表,然后填充用八行代表汽车目前在库存。

定期销售经理喜欢看到他InvoicePriceRatio通过运行清单5中的查询

SELECT CarName, InvoicePrice/StickerPrice*100.0 AS InvoicePriceRatio 
FROM CarInventory;

清单5:InvoicePriceRatio查询

当经理运行该查询,她注意到有许多类似的汽车一样InvoicePrice数量有不同InvoicePriceRatio值。 最大化发票标价比她问她的IT支持编写一个查询,该查询将更新StickerPrice在她所有的汽车每辆车相同CarName 有相同的价值InvoicePriceRatio。 她希望这家伙来设置StickerPrice相同的值作为最高标价CarName。 这样所有的汽车一样CarName都有相同的价值StickerPrice价值。 完成这个更新的CarInventory表,这家伙运行清单6中的transact - sql语句,其中包含相关子查询。

UPDATE CarInventory  
SET StickerPrice = (SELECT MAX(StickerPrice) FROM CarInventory Inner_CI WHERE Inner_CI.CarName = Outer_CI.CarName)  
FROM CarInventory Outer_CI; 

清单6:相关子查询来更新CarInventory最大标价

清单8中的代码使用CarName从外部查询的相关子查询来确定最大StickerPrice为每一个独特的CarName。 这个最大StickerPrice然后使用相关子查询中找到的值来更新StickerPrice值为每个CarInventory有相同的记录CarName

相关子查询的性能注意事项

有些性能考虑你应该意识到写作时transact - sql语句包含相关子查询。 性能不是坏当外层查询包含一个小的行数。 但当外层查询包含大量的行不规模从性能角度来看。 这是因为相关子查询中的每个候选人需要执行行外部查询。 因此,当外部查询包含越来越多的候选人行相关子查询多次执行,因此transact - sql语句将需要更长的时间。 如果你发现你的相关子查询transact - sql语句的性能没有达到您的需求,那么您应该寻找替代解决方案,比如使用一个内部或外部连接操作的查询,或返回一个小数量的候选人的行从外部查询。

总结

相关子查询是一种内在的查询,包括一个或多个列从外部查询。 相关子查询是每个外部的候选人行执行一次查询。 因为相关子查询包含一个列外查询不能独立运行的外部查询。 相关子查询的地方,虽然没有很好地扩展从性能角度来看当有大量的候选人中确定行外部查询。

问题和答案

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

问题1

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

1、一个或多个列的内部查询用于限制相关子查询的结果。

2、一个或多个列的内部查询所使用的选择列表相关子查询。

3、一个或多个列从外部查询用于限制相关子查询的结果。

4、一个或多个列从外部查询所使用的选择列表相关子查询。

问题2

选择所有的以下相关子查询语句,是正确的

1、随着候选人的行数的增加性能数据库引擎执行的sql语句,其中包含一个相关子查询得到改善。

2、每个候选人的相关子查询会执行一次行从外部查询。

3、相关子查询会引用一个或多个列的内部查询。

4、当使用子查询相关条款内查询将对每个候选人行执行一次返回的GROUP by子句。

问题3:

相关子查询就像一个正常的子查询,和相关子查询可以运行独立于整个transact - sql语句(真或假)。

  1.  
  1. 答案:

    问题1:

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

    问题2:

    正确答案是b和d是不正确的,因为随着候选人的行数的增加相关子查询被多次执行,和数据库引擎执行的sql语句的性能恶化。 c是错误的,因为相关子查询必须包含一个或多个行从外部查询,而不是内在的查询。

    问题3:

    正确的答案是b。如果你尝试运行数据库引擎执行完整的sql语句的独立相关子查询,相关子查询语句将失败。

转载于:https://www.cnblogs.com/705xinguan/p/7873382.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/571586.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

筛选中很容易粘贴到被隐藏部分_excel复制粘贴:如何将数据粘贴到筛选区域中?...

编按:哈喽,大家好!看到标题相信大家都会纳闷吧。复制粘贴不是excel中最简单,最基础的操作吗?怎么可能90%的人都不会呢?今天咱们要说的可不是普通的复制粘贴,而是将数据复制粘贴到筛选后的区域中…

python 发邮件_Python发邮件告别smtplib,迎接zmail

之前介绍过smtplib发邮件代码,直到今天仍有人在这里遇到问题。而且代码复杂,解释起来很麻烦,今天给大家介绍一个新的发邮件方法——zmailzmail的优势自动填充头信息将一个字典映射为email,构造邮件相当于构造字典自动寻找邮件服务…

重复数据_MongoDB 自动过滤重复数据

摘要:使用 update_one() 方法而不是 insert_one() 插入数据。相信你一定有过这样的经历:大晚上好不容易写好一个爬虫,添加了种种可能出现的异常处理,测试了很多遍都没有问题,点击了 RUN 开始正式运行 ,然后…

多个canvas画布合并_canvas的基础入门

nvas是定义在浏览器上的画布。它不仅仅是一个标签元素更是一个编程工具是一套编程的接口。利用它可以开发出很多东西,比如动画,游戏,动态的图表等富有变现力和感染力的应用。还可以开发出绚丽的3D动态效果。接下来我们一起学习!一…

AngularJS 计时器

<div ng-controller"MyController"><!--显示$scope.clock的now属性--><h1>hello {{clock.now}}</h1><!--显示$scope.clock&#xff0c;里面有一个属性now--><h1>hello {{clock}}</h1> </div><script src"ht…

Rulo扫地机器人app_扫地机器人怎么选?扫地机器人怎么用

扫地机器人又称自动打扫机、智能吸尘、机器人吸尘器等&#xff0c;是智能家用电器的一种&#xff0c;能凭借一定的人工智能&#xff0c;自动在房间内完成地板清理工作。一般采用刷扫和真空方式&#xff0c;将地面杂物先吸纳进入自身的垃圾收纳盒&#xff0c;从而完成地面清理的…

python七巧板三角形_用七巧板拼出14种三角形,这才是图形认知的神器!

原标题&#xff1a;用七巧板拼出14种三角形&#xff0c;这才是图形认知的神器&#xff01;随着幼升小越来越注重孩子的图形认知能力&#xff0c;很多名校幼升小都选择了七巧板作为考验孩子的题目&#xff01;比如北京实验二小09年的幼升小考题中&#xff0c;就有一道“用七巧板…

Docker 容器的常用命令

容器常用的管理命令1. 创建并启动容器 docker rundocker run 创建并启动一个容器&#xff0c;在run后面加上-d参数&#xff0c;则会创建一个守护式容器在后台运行。注&#xff1a; docker run将在下一章节中具体描述2. 查看docker ps -a 查看已经创建的容器3. 停止 docke…

如何在graphpad表示出正负误差_Graphpad Prism:SCI科研论文中误差连线图怎么做

这是一篇高分SCI论文中的图&#xff0c;图中间为均值、均值上下方的浅色为数据误差&#xff0c;即误差连线图。今天跟大家分享如何使用GraphpadPrism作这么好看的图!打开软件&#xff0c;选择XY&#xff0c;按照下图新建折线图&#xff1a;输入数据&#xff1a;得到下图所示折线…

python3123_使用sox和python,基于时间戳列表对音频区域进行静音处理

我有一个音频文件。我有一堆[开始&#xff0c;结束]时间戳段。在我想要实现的目标&#xff1a;假设音频长度为6:00分钟。我有段是&#xff1a;[[0.0,4.0]&#xff0c;[8.0,12.0]&#xff0c;[16.0,20.0]&#xff0c;[24.0,28.0]]在我把这两个传递给soxpython之后&#xff0c;输…

ajax post 传参数加引号和不加引号的区别

1.前言 用ajax技术&#xff0c;type&#xff1a;post&#xff0c;data&#xff1a;参数列表。参数列表就是一个JSON数据&#xff0c;但key可以加引号&#xff0c;也可以不加引号&#xff0c;那总有区别的。 2.区别 var d2 "two"; var d4 "four"; var idAr…

工业机器人专业展板图片_南充职业技术学院工业机器人专业线下课程开展情况...

2020年5月18日&#xff0c;南充职业技术学院线下课程已全面展开&#xff0c;下面是工业机器人技术专业的开课情况。历时4个多月的假期&#xff0c;即将开课。在开课前两天&#xff0c;我司专业教师到学院检查维护机器人设备&#xff0c;以保障学生们能够正常使用工业机器人相关…

vmware挂载san存储_细述企业级存储NAS和SAN差异

常见服务器磁盘类型SAS&#xff1a;容量小&#xff0c;300G&#xff0c;600G&#xff0c;价格贵SATA&#xff1a;容量大&#xff0c;4T&#xff0c;不支持热插拔&#xff0c;价格低假SAS&#xff1a;容量大&#xff0c;支持热插拔&#xff0c;价格低&#xff0c;(就是SAS接口的…

蓝牙核心技术了解(蓝牙协议、架构、硬件和软件笔记)

声明&#xff1a;这篇文章转载beautifulzzzz笔记&#xff0c;网址&#xff1a;http://www.cnblogs.com/zjutlitao/&#xff0c;其中比较多的受益于xubin341719的蓝牙系列文章&#xff0c;同时还有其他网上作者的资料。由于有些文章只做参考或统计不足&#xff0c;如涉及版权请在…

初中英语多词性单词怎么办_高考英语阅读理解生僻单词太多怎么办?十大招数帮到你...

英语阅读理解生僻单词太多怎么办&#xff1f;今天&#xff0c;胡老师告诉你猜词十大招数&#xff0c;帮助同学们英语考试拿高分。01 构词法阅读中常常会遇到一些由熟悉的单词派生或合成的新词。掌握构词法对猜测词义很有帮助。如&#xff1a;unforeseeable.这个词&#xff0c;可…

springboot jwt token前后端分离_基于Spring Boot+Spring Security+JWT+Vue前后端分离的开源项目...

一、前言最近整合Spring BootSpring SecurityJWTVue 完成了一套前后端分离的基础项目&#xff0c;这里把它开源出来分享给有需要的小伙伴们功能很简单&#xff0c;单点登录&#xff0c;前后端动态权限配置&#xff0c;前端权限精确到 按钮 级别&#xff0c;后端权限精确到 url …

三维数组设置索引_python3三维数据结构 —— panel

注意&#xff1a;现状问题&#xff1a;新版的pandas库已经移除了数据结构panel解决办法&#xff1a;使用MultiIndex的DataFrame结构替代下一篇文章介绍 MultiIndex----------------------------------------------------------------------------------------------简介&#x…

springboot 微服务_使用 Docker 部署 Spring Boot微服务

Docker 技术发展为微服务落地提供了更加便利的环境&#xff0c;使用 Docker 部署 Spring Boot 其实非常简单&#xff0c;这篇文章我们就来简单学习下。首先构建一个简单的 Spring Boot 项目&#xff0c;然后给项目添加 Docker 支持&#xff0c;最后对项目进行部署。一个简单 Sp…

佛说十善业道经略谈

5戒分别是杀盗淫妄酒。10善业分别是身业有3&#xff1a;杀盗淫&#xff0c;口业有4 &#xff1a;2舌、绮语、恶口、妄语&#xff0c; 意业有3&#xff1a;贪嗔痴 。 这部经的提是一部人法立题的经。佛是人 &#xff0c;十善业是法。 佛在这里是专指释迦牟尼佛&#xff0c;这里面…

weblogic修改banner_WeblogicScanV1.3

WeblogicScanWeblogic一键漏洞检测工具&#xff0c;V1.3软件作者&#xff1a;Tide_RabbitMask免责声明&#xff1a;Pia!(&#xff4f; ‵-′)ノ”(ノ﹏本工具仅用于安全测试&#xff0c;请勿用于非法使用&#xff0c;要乖哦~V 1.3功能介绍&#xff1a;提供一键poc检测&#xff…