发布网友 发布时间:2022-04-22 20:48
共16个回答
懂视网 时间:2022-05-02 12:40
Gregory Larsen,2016/01/01(第一次发布:2014/01/29)原文链接:http://www.sqlservercentral.com/articles/Stairway+Series/104517/
此系列
本文是楼梯系列的一部分:T-SQL楼梯:超越基础
从他的楼梯到T-SQL DML,Gregory Larsen涵盖了更多的高级方面的T-SQL语言,如子查询。
在您开始创建超出基本Transact-SQL语句的更复杂的SQL代码时,您可能会发现需要使用其他SELECT语句的结果来限制查询。 当在父Transact-SQL语句中嵌入SELECT语句时,这些嵌入式SELECT语句被称为子查询或相关子查询。 在“超越基础”楼梯的这个层次上,我将讨论一个子查询的不同方面,在将来的一个层面上,我将讨论相关的子查询。
什么是子查询?
子查询只是一个SELECT语句,它包含在另一个Transact-SQL语句中。可以在任何可以使用表达式的地方使用子查询。许多子查询返回单个列值,因为它们与比较运算符(=,!=,<,<=,>,> =)或表达式结合使用。当子查询不用作表达式或使用比较运算符时,它可以返回多个值。此外,子查询甚至可以在FROM子句或关键字EXISTS中使用时返回多个列和值。
子查询容易在Transact-SQL语句中发现,因为它将是括号中的SELECT语句。由于子查询包含在Transact-SQL语句中,因此子查询通常称为内部查询。而包含子查询的Transact-SQL语句被称为外部查询。子查询的另一个特点是可以独立于外部查询运行,并且将无错误地运行,并且可能返回一组行或空行集。
子查询的另一种形式是相关子查询。但是相关的子查询不能独立于外部的Transact SQL语句运行。相关子查询使用外部查询中的列或列来约束从相关子查询返回的结果。这对于本文的相关子查询足够了。我将在未来的楼梯文章中探索相关的子查询。
使用子查询时还需要考虑以下几点:
l ·不允许从子查询返回文本,文本和图像数据类型
l ·除非使用TOP操作符,否则ORDER BY子句不能用于子查询
l ·不能更新使用子查询的查看
l ·COMPUTE和INTO子句不能在子查询中使用
子查询示例数据示例
为了演示如何使用子查询,我将需要一些测试数据。 而不是创建自己的测试数据,我的所有示例都将使用AdventureWorks2008R2数据库。 如果您想跟随并在环境中运行我的示例,那么您可以从这里下载AdventureWorks2008R2数据库:http://msftdbprodsamples.codeplex.com/releases/view/93587
返回单个值的子查询的示例
如上所述,在表达式中使用的子查询或返回比较运算符一侧的值需要返回单个值。 Transact-SQL语句中有许多不同的地方,需要一个子查询来返回单个列值,例如在选择列表中WHERE子句等。在本节中,我将提供一系列示例,演示如何使用子查询 作为表达式或与比较运算符以满足不同的业务需求。
列列表中的子查询
列列表中的子查询是SELECT语句,它返回放置在SELECT子句的列列表中的单个列值。 为了演示如何在选择列表中使用子查询,我们假设我们必须从具有以下业务需求的SELECT语句生成一个结果集:
l ·返回所有Sales.SalesOrderHeader记录有什么有OrderDate等于“2007-02-19 00:00:00.000”
l ·通过SalesOrderID列出返回的记录
l ·返回最后一行的RowNumber为1的行的每行数,下一个最大的RowNumber为2等
l ·结果集需要一个名为TotalOrders的列,需要填充OrderDate等于“2007-02-19 00:00:00.000”的总订单数量。
清单1中列出了满足这些要求的代码。
SELECT ROW_NUMBER() OVER (ORDER BY SalesOrderID) RowNumber
, (SELECT COUNT(*)
FROM [Sales].[SalesOrderHeader]
WHERE ModifiedDate = ‘2007-02-19 00:00:00.000‘)
AS TotalOrders
, *
FROM [Sales].[SalesOrderHeader]
WHERE OrderDate = ‘2007-02-19 00:00:00.000‘;
清单1:列列表中的子查询
在这个单一的Transact-SQL语句中,您会看到两个不同的SELECT子句。 子查询是嵌入在清单1中的语句中间的SELECT语句,它在它周围有括号。 我已经删除了子查询语句,并将其放在清单2中,以防您想要测试以验证它可以独立于完整的Transact-SQL语句运行。
SELECT COUNT(*)
FROM [Sales].[SalesOrderHeader]
WHERE OrderDate = ‘2007-02-19 00:00:00.000‘
清单2:清单1中的子查询语句
通过将此子查询列在列列表中,清单1中的此Transact-SQL语句可以对OrderDate为“2007-02-19 00:00:00.000”的SalesOrderHeader行的数量进行计数,并将该信息与详细信息一起返回 有关具有相同OrderDate值的Sales.SalesOrderHeader记录的行信息。
WHERE子句中子查询的示例
有时你想根据SELECT语句的结果来驱动WHERE子句条件。 当您在WHERE子句中的SELECT语句时,此SELECT语句实际上是一个子查询。 要演示在WHERE子句中使用子查询,假设您需要显示包含购买超大型长袖徽标运动衫的Sales.SalesOrderDetail记录。 清单3中的代码通过使用子查询来满足我的显示要求。
SELECT * FROM [Sales].[SalesOrderDetail]
WHERE ProductID = (SELECT ProductID
FROM [Production].[Product]
WHERE Name = ‘Long-Sleeve Logo Jersey, XL‘);
清单3:WHERE子句中的子查询
清单3中的子查询位于WHERE条件的右侧。 此子查询标识Product.Product记录的ProductID,其中产品名称为“Long-Sleeve Logo Jersey,XL”。 此子查询允许我找到具有与“Long-Sleeve Logo Jersey,XL”的产品名称相关联的ProductID的所有Sales.SalesOrderDetail记录。
使用子查询来控制TOP条款的示例
使用TOP子句返回的行数可以由表达式控制。 清单5中的代码标识了应该根据TOP子句中的子查询返回的Sales.SalesOrderDetail行的数量。
SELECT TOP (SELECT TOP 1 OrderQty
FROM [Sales].[SalesOrderDetail]
ORDER BY ModifiedDate) *
FROM [Sales].[SalesOrderDetail]
WHERE ProductID = 716;
清单4:TOP子句中的子查询
清单4中的代码使用从子查询返回的OrderQty值来标识将在TOP子句中使用的值。 通过使用子查询来控制TOP子句返回的行数,可以构建一个子查询,以便在运行时动态地识别从查询返回的行数。
子条款示例
为了演示在HAVING子句中使用子查询,假设您具有以下业务要求:
生成包含Sales.SalesOrderHeader.OrderDate和每个日期的订单数量的结果集,其中订单数量超过“2006-05-01”上执行的订单数量。
为了满足这个要求,我开发了清单6中使用HAVING子句中的子查询的查询。
SELECT count(*), OrderDate
FROM [Sales].[SalesOrderHeader]
GROUP BY OrderDate
HAVING count(*) >
(SELECT count(*)
FROM [Sales].[SalesOrderHeader]
WHERE OrderDate = ‘2006-05-01 00:00:00.000‘);
清单5:HAVING子句中的子查询
清单5中的代码具有HAVING子句右侧的子查询,并在我的子查询中使用COUNT函数来确定“2006-05-01”上的订单数量。
在函数调用中使用子查询的示例
要演示在函数调用中使用子查询,假设您需要显示OrderDate和每个Sales.SalesOrderHeader记录的最大OrderDate之间的天数。 清单6中的代码符合此要求。
SELECT SalesOrderID
, OrderDate
,DATEDIFF
(
dd,OrderDate
,(SELECT MAX(OrderDate)
FROM [Sales].[SalesOrderHeader])
) AS DaysBetweenOrders
,(SELECT MAX(OrderDate)
FROM [Sales].[SalesOrderHeader])
AS MaxOrderDate
FROM [Sales].[SalesOrderHeader];
清单6:函数调用中的子查询
清单6中的代码有两个不同的子查询。两个子查询返回Sales.SalesOrderHeader表中的最大OrderDate。但是第一个子查询用于将日期传递给DATEDIFF函数的第二个参数。
返回多个值的子查询的示例
我迄今为止的所有示例都包含仅在单个列中返回单个值的子查询。并不是所有的子查询都有这个要求。接下来的几个例子将使用返回多个值和/或多个列的子查询。
FROM子句中的子查询示例
在FROM子句中,通常会标识您的Transact-SQL语句将对其执行的表或表的集合。每个表提供一组记录,您的查询将用于确定查询的最终结果集。子查询可以被认为是返回一组记录的查询,因此它可以像FROM表一样在FROM子句中使用。清单7中的查询显示了我如何在FROM子句中使用子查询。当在FROM子句中使用子查询时,从子查询生成的结果集通常称为派生表。
SELECT SalesOrderID
FROM (SELECT TOP 10 SalesOrderID
FROM [Sales].[SalesOrderDetail]
WHERE ProductID = 716
ORDER BY ModifiedDate DESC) AS Last10SalesOrders;
清单7:FROM子句中的子查询
·清单7中的代码使用FROM子句中的子查询来创建一个名为Last10SalesOrders的表别名。 我的子查询返回包含ProductID为716的最后10个Sales.alesOrderDetail记录。
清单7中的代码是一个非常简单的例子,说明如何在FROM子句中使用子查询。 通过在FROM子句中使用子查询,您可以轻松地构建更复杂的FROM语法,该语法将子查询的结果与其他表或其他子查询相结合,如清单8所示。
SELECT DISTINCT OrderDate
FROM (SELECT TOP 10 SalesOrderID
FROM [Sales].[SalesOrderDetail]
WHERE ProductID = 716
ORDER BY ModifiedDate DESC) AS Last10SalesOrders
JOIN [Sales].[SalesOrderHeader] AS SalesOrderHeader
ON Last10SalesOrders.SalesOrderID = SalesOrderHeader.SalesOrderID
ORDER BY OrderDate
清单8:使用实际表连接派生表
在清单8中,我看到了我在清单7中创建的子查询/派生表,并将其与SalesOrderHeader表相加。 通过这样做,我可以确定最后10次订购ProductID = 716的OrderDate。
使用具有IN关键字的子查询的示例
您可以编写一个返回列的多个值的子查询的地方是当您的子查询生成与IN关键字一起使用的记录集时。 清单9中的代码演示了如何使用子查询将值传递给IN关键字。
SELECT * FROM [Sales].[SalesOrderDetail]
WHERE ProductID IN
(SELECT ProductID
FROM [Production].[Product]
WHERE Name like ‘%XL%‘);
清单9:使用子查询将值传递给IN关键字
清单9中的代码使用一个子查询从Product.Product表中返回不同的ProductID值,其名称包含字符“XL”。 然后在IN关键字中使用从子查询返回的这些ProductID值来约束从Sales.SalesOrderDetail表返回哪些行。
在修改数据的语句中使用子查询的示例
到目前为止,我的所有示例一直在演示如何在SELECT语句的不同部分中使用子查询。 也可以在INSERT,UPDATE或DELETE语句中使用子查询。 清单10中的代码显示了如何在INSERT语句中使用子查询。
DECLARE @SQTable TABLE (
OrderID int,
OrderDate datetime,
TotalDue money,
MaxOrderDate datetime);
-- INSERT with SubQuery
INSERT INTO @SQTable
SELECT SalesOrderID,
OrderDate,
TotalDue,
(SELECT MAX(OrderDate)
FROM [Sales].[SalesOrderHeader])
FROM [Sales].[SalesOrderHeader]
WHERE CustomerID = 29614;
-- Display Records
SELECT * FROM @SQtable;
清单10:INSERT语句中的子查询
在清单10中的代码中,我使用一个子查询来计算要插入列MaxOrderDate的值。这只是在INSERT语句中如何使用子查询的一个示例。请记住,也可以在UPDATE和/或DELETE语句中使用子查询。
子查询和JOIN之间的性能考虑
如果您已阅读由Microsoft生成的“子查询基础知识”文档(http://technet.microsoft.com/en-us/library/ms189575(v=sql.105).aspx),那么您可能已经在此语句中运行包含子查询的语句的性能:
“在Transact-SQL中,包含子查询的语句和不具有语义相似的版本的语句通常没有性能差异。
要将使用子查询的查询的性能与不使用子查询的等效查询进行比较,我将在清单3中重写我的子查询以使用JOIN操作。清单11显示了我重写的JOIN查询,相当于清单3中的查询。
SELECT SOD.*
FROM [Sales].[SalesOrderDetail] AS SOD
INNER JOIN
[Production].[Product] AS P
ON SOD.ProductID = P.ProductID
WHERE P.Name = ‘Long-Sleeve Logo Jersey, XL‘;
清单11:与清单3中的查询相当的JOIN查询
要比较使用子查询的清单3中的查询的性能和使用JOIN的清单11中的查询,我将使用清单12中的代码运行两个查询。
SET STATISTICS IO ON;
SET STATISTICS TIME ON;
-- Listing 3 query
SELECT * FROM [Sales].[SalesOrderDetail]
WHERE ProductID = (SELECT ProductID
FROM Production.Product
WHERE Name = ‘Long-Sleeve Logo Jersey, XL‘);
-- Listing 11 query
SELECT SOD.*
FROM [Sales].[SalesOrderDetail] AS SOD
INNER JOIN
[Production].[Product] AS P
ON SOD.ProductID = P.ProductID
WHERE P.Name = ‘Long-Sleeve Logo Jersey, XL‘;
清单12:测试清单3和清单4的性能代码
在运行列表12中的代码之后,我回顾了“SET STATISTICS”语句生成的消息。通过查看统计信息,我发现这两个查询对SalesOrderDetail表都有3,309个逻辑读取,对于Product表有两个逻辑读取,每个使用31 ms的CPU。另外我查看了SQL Server为这两个查询创建的执行计划。我发现SQL Server为两者生成了相同的执行计划。因此,对于我的情况使用子查询或JOIN查询产生了等效的性能,正如微软所记录的那样。
概要
子查询是嵌入另一个Transact-SQL语句的SELECT语句。子查询可以独立于外部查询运行,因此有时也称为独立查询。记住,任何时候你有一个子查询代替一个表达式,或者与比较运算符一起使用,它只能返回一个列和值。通常可以使用JOIN逻辑重写子查询。子查询是帮助您构建更复杂的Transact-SQL语句以满足业务需求的强大工具。
问题和答案
在本节中,您可以通过回答以下问题来查看您使用子查询概念了解的内容。
问题1:
完成这个句子“一个子查询是另一个Transact-SQL语句中的SELECT语句,_____________________”。
·不能独立于完整的查询运行。
·来自外部查询的引用列。
·当独立于外部查询运行时,它将返回结果。
问题2:
什么时候子查询只需要一个列和值才能返回(选择所有适用的)?
·在FROM子句中使用子查询时
·在IN子句中使用子查询
·在表达式中使用子查询时
·子查询与比较运算符一起使用时
问题3:
在WHERE子句中使用一个子查询的Transact-SQL语句总是比不包含子查询(True或False)的等效查询执行得慢。
·True
·False
回答:
问题1:
正确的答案是c。子查询可以独立于外部查询运行,并返回结果。它不需要来自外部查询的任何列,如果它有来自外部查询的列,它将被称为相关子查询。
问题2:
正确的答案是c和d。当用作表达式或在比较操作中时,子查询需要返回一个列值。当子查询与IN关键字一起使用时,它可以返回列的单个或多个值。如果在FROM子句中使用子查询,它只能返回一列和一个值,但也可以返回多个列和值。
问题3:
正确答案是错误的。 SQL Server优化器非常聪明,很可能为两个等效查询计算相同的执行计划。如果包含子查询的查询的执行计划和没有子查询的查询的执行计划最终都具有相同的执行计划,则两个查询将具有相同的性能。
阶梯T-SQL:超越基础2级:编写子查询
标签:有一个 display 应该 top 通过 简单的 示例 t-sql语句 别名
热心网友 时间:2022-05-02 09:48
世上无难事,只怕有心人。
Java是编程语言中比较难学的一门语言,它的难度并不低,相对比于C语言、Python语言来说,他们的学习难度要比Java轻松很多;
Java的学习中最难得就是,各种各样的框架,框架的使用、整合、最后项目;
学习Java刚开始我们要学习各种各样的基础知识:
Java的基础:
数据结构和算法、集合(容器)、IO流、多线程、封装、多态、继承等等
数据库的基础:
MySQL基础、MySQL 增删改查语句、数据库对象、JDBC、反射和注解等
Javaweb基础知识:
前端的基础:
JS(JavaScript)、jQuery、HEML、CSS等
当我们学完这些基础知识以后我们将迈入Java中的高级阶段 JavaEE
这个阶段中会需要我们将所有的,知识总结在一起揉吧揉吧和一块,“难就难在这里”以我对学习Java来看就是这种想象,起个名词“学英语”;
就是那种 “ABCDEFG···”我都会,但是合在一起的话我们就变得,不能理解甚至无从下手。原本很简单的基础知识,什么 封装多态简单、什么 HTML/CSS简单、什么数据库简单!!但是他们集合在一起会导致我们不知道从哪里开始
学习Java不止要靠毅力、脑力、思维力,还要靠人际交流问题需要靠你的花言巧语找大牛为你指点江山,走上成功之路!
希望会给大家带来帮助!
热心网友 时间:2022-05-02 11:06
关于java难不难的问题,不同的人肯定有不同的看法,掌握了方法,就可以用更有效率的方式进行学习。java是目前主流的开发语言,程序员不论是大数据、云计算、web前端、后端开发等都需要从java学起,如果你想计入IT高薪行列,建议学java!
java学习内容主要有:
①JAVA编程基础(基础语法、面向对象、和谐特性等)
②WEB应用开发(静态网页制作、Oracle数据库、Java Web开发技术、Linux技术、网站性能与安全、软件工程开发流程、Java Web和谐等)
③企业级框架开发(数据结构与算法、SSH框架、JavaEE和谐等)
④项目实训
互联网行业目前还是最热门的行业之一,学习IT技能之后足够优秀是有机会进入腾讯、阿里、网易等互联网大厂高薪就业的,发展前景非常好,普通人也可以学习。
想要系统学习,你可以考察对比一下开设有相关专业的热门学校,好的学校拥有根据当下企业需求自主研发课程的能力,能够在校期间取得大专或本科学历,中博软件学院、南京课工场、南京北大青鸟等开设相关专业的学校都是不错的,建议实地考察对比一下。
祝你学有所成,望采纳。
热心网友 时间:2022-05-02 12:40
我是从事Java方面工作的,简单的给你一些建议吧。热心网友 时间:2022-05-02 14:32
关于难度,其实学什么东西都是一样的,入门简单,深入不容易,Java也是,如果您是零基础,或者转行,不建议自学,报班是性价比最高的选择;热心网友 时间:2022-05-02 16:40
java入门不难的,当然,比起C语言那种有点入门傻瓜式的语言难了点。说java精通易得肯定是java菜鸟或者道听途说,他们大概以为学会java语法就学会了java。语言是不难,关键是算法、数据结构以及设计模式之类的,想成为真正的高手,这是学任何语言都得掌握的,你学java不是只想做一个只知道码代码的吧。会英语不是让你写什么东西,是要你能读资料,语法不会无所谓的。语言本身并不要求你懂英语的。热心网友 时间:2022-05-02 19:04
不是很难学,但最好有一定的英语基础热心网友 时间:2022-05-02 21:46
java不是很难学,只要你努力了,一般都学的不错的,就业前景去看下招聘网站就行了,一般java开发维护是需求最大的。热心网友 时间:2022-05-03 00:44
这是每个初学者都必须经历的过程,也没什么特别好的方法,只有先把代码理解性的背下来。在不看书的情况下,自己再打上几遍。时间长了,自然就会了,要勇于去尝试没什么对不对的。只要自己让为这样写对,就要试试。很多东西都很活,只有自己试过才会知道怎么用。不如做些简单,自己又感兴趣小东西来建立信心。 才刚刚学Java基础别就这样抱怨,还有很多东西学完了才算是入门,不是吓唬你,想要做开发还需要学习html,数据库,JavaScript,jsp;Spring,struts,Hibernate三的框架还有服务器的应用.这些都是基本的。加油吧朋友,我很看好你喔!热心网友 时间:2022-05-03 03:58
Java已经成为如今互联网企业使用广泛的语言之一,Java开发市场需求大、发展前景广,吸引了越来越多的人前来学习。对于零基础的小白而言,想要系统的学习Java方法,学习路线
第一步:对于Java的基本认知
学习Java,首先要明白Java是什么,其未来的发展方向和应用场景有哪些?当然,很多从业者和求学者往往看重的是Java行业的薪资水平,这样考虑固然无错,但是对于深刻理解Java却并无实际意义。可以看看专业分析Java的书籍,这对于后期的学习将有着巨大的助力作用。
第二步:理论知识学习
这一过程尤为重要,毕竟这是学习Java的关键,而且,这一过程对于系统化的要求更高,如何循序渐进,有方式有目的的学习,将是小白更加快速的学懂Java的关键。所以给大家分享一个学习Java知识点的先后顺序安排,希望对大家有所帮助。
1、Java 基础以及 Web 开发基础—小程序项目阶段,让学员可掌握Java 基本面向对象知识、Java 常用集合的使用、JDBC 与 MySQL 基础、HTML/CSS/JavaScript 前端基础技术、 Servlet 编写服务端程序等,同时熟练使用 IDEA 开发工具,能实现简单的小程序;
2、Java高级基础、SSM 前端框架、代码管理、持续集成,是进阶阶段,让学员可以深入理解Java面向对象相关知识点,可以胜任Java 初级软件工程师、Web 初级前端开发工程师、初级 BI 工程师等岗位。
3、服务与分布式解决方案,让学员掌握Linux、Docker、Vue、SpringBoot、Shiro、分布式事务的使用等,可以熟练使用Docker 完成项目部署,胜任Java 中级开发工程师等岗位;
4、大型互联网解决方案,让学员掌握JUC、Zookeeper、Dubbo、MySQL 高级、MyCat和微信小程序以及微信支付的开发等内容,可以胜任Java 高级软件工程师等岗位。
第三步、真实实训项目、培养实操能力
如今互联网上关于Java的应用案例有很多,也有很多的实训项目,大家可以去进行独立的实操
热心网友 时间:2022-05-03 07:30
好就业热心网友 时间:2022-05-03 11:18
俗话说态度决定一切,一个人的学习态度相当重要,而一个良好的态度不仅会提高你的效率,而且还会影响效果。热心网友 时间:2022-05-03 15:22
不难学,毕竟Java只是一种语言,仅此而已。它与我们的母语和英语没有什么不同。只是它适用于电脑、手机等非生物,但基本控制结构等。所有的语言都是相似的。热心网友 时间:2022-05-03 19:44
现在Java培训机构确实参差不齐,常见的有线上视频或者直播学习和线下全日制面授形式,当然形式不一样,时间也不一样!现在*居多,有好有坏,费用有多有少。最重要的是自己在学习时要好好学习了。具体根据不同的培训机构而定,建议了解清楚其课程体系和上课形式。热心网友 时间:2022-05-04 00:22
可能你还没有达到人家的技术要求,建议你到动力节点java学习,我就在这机构学的,当时在北京培训的,听说在深圳也要开新校区,你看那个近,就近原则就可以热心网友 时间:2022-05-04 05:16
现在Java培训机构确实参差不齐,常见的有线上视频或者直播学习和线下全日制面授形式,当然形式不一样,时间也不一样!现在*居多,有好有坏,费用有多有少。最重要的是自己在学习时要好好学习了。具体根据不同的培训机构而定,建议了解清楚其课程体系和上课形式。