SELECT与WHERE在相关子查询中的应用

2019-11-03 14:07李增祥
电脑知识与技术 2019年23期

李增祥

摘要:相关子查询是那些能够表不可能为可能的事物之一,此外,它们经常把几行代码变成一行,并且带来相应性能的提升,伴随相关子查询的问题是,它们通常需要有别于常规的彻底不同的思维方式,相关子查询在SQL学习中是最容易学会的概念,但也是最容易被遗忘的概念,因为相关子查询与正常的思维方式正好相反,本文介绍相关子查询的概念,以及如何在WHERE字句和SELECT子句中使用相关子查询,如果掌握这两点,当需要从查询中寻找所有的性能时,将会成为非常好的工具。

关键词:相关子查询;WHERE;SELECT

中国分类号:G712          文献标识码:A

文章编号:1009-3044(2019)23-0005-02

开放科学(资源服务)标识码(OSID):

SQL子查询可以分为 相关子查询和嵌套子查询两类,嵌套子查询的执行不依赖与外部的查询[1],它的执行过程是先执行子查询,其结果不被显示,而是传递给外部查询,作为外部查询的条件使用;然后再执行外部查询,并显示整个结果。嵌套子查询一般可以分为两种,一种是返回单值的子查询,另外一种则是返回一个列表的子查询。相关子查询的执行依赖于外部查询,多数情况下是子查询的WHERE子句中引用了外部查询的表。

1相关子查询的概念

相关子查询是一种其内部查询和外部查询相互交叉的数据检索方法.在相关子查询中[2],信息是双向而非单向进行的,内部查询根据外部查询提供的信息执行,反之亦然,从概念上讲包含相关子查询的语句在执行时部能分为一先一后两个步骤,首先外部查询得到一条记录并将其传入到内部查询,内部查询基于刚刚传入的值执行,然后内部查询从其结果中把值传回到外部查询[3],通过外部查询使用这些值来完成其处理。也就是说,相关子查询无法独立于外部查询进行计算,因为内部查询使用了外部语句的值。即,会针对外部语句中的每一行来执行内部查询[4]。因此,内部查询的结果取决于外部语句中正在计算的活动行。

2 Select列表中的相关子查询

子查询也能用来在选择结果中提供一种不同类型的答案。这种情形通常出现在要找寻的信息与查询中的其他数据全然不同的时候(例如,当想要在一个字段上进行聚集,但却不希望因此而影响返回的其他字段)。

为了实验,我们需要创建一个数据库Works,假设我们要在数据库Works中查找的是顾客的名字以及首次订购的日期,数据库中包含的数据表和他们之间的相互关系如下图1所示。

想要得到顾客的名字,这意味着必须要用到customers表,此外,我们不再需要构造任何类型的条件——这里要获取的是所有没有任何限制的顾客,我们只是想知道他们第一次订购的日期,查询命令为:

SELECT c.LastName,

{SELECT MIN{OrderDate}

FROM Sales.SalesOrderHeader c

WHERE c.ContactID = c.ContactID}

AS  “Order Date”

FROM Person.Contact c

显示结果如表1所示:

如果浏览所有的数据,会看到可能在有一些行的OrderDate列中有NULL值,那是因为在SalesOrderHeader表中没有与Customers表中(外部查询)当前的记录相匹配的记录。

3 where 子句中的相关子查询

在这里我们继续用上边的数据库做实验,想要查询每一位顾客在系统中的第一张订单的OrderID和OrderDate,根据查询输出要求,结果中要有OrderDate、OrderID以及CustomerID,这些信息都能在SalesOrderHeader中找到,想要知道每一位顾客在系统中的订单日期,相关子查询中,我们需要得到每一位顾客的最早的日期,解决这个查询,可以通过两个查询来完成,第一个查询中需要创建一个临时表(临时表中包CustomerID,MIN(OrderDate)两个字段),在第二个查询中联接回该临时表,如果要通过一个查询来实现,必须找到一个查找每个人的方法,该方法可以用内部查询来解决,该查询基于外部查询中当前的CustomerID执行查找,然后需要把值返回给外部查询,以便外部查询能够基于最早下订单的日期来进行查找。SQL命令为:

SELECT o1.CustomerID,o1.SalesOrderID,o1.OrderDate FROM SalesOrderHeader o1

WHERE o1.OrderDate=(SELECT MIN(O2.OrderDate) FROM Sales.SalesOrderHeader o2 WHERE o2.CustomerID=O1.CustomerID) ORDER BY CustomerID

在代碼中,外部查询看起来与嵌套子查询非常类似,然而,内部查询对于外部查询有一个明显的引用。内部查询和外部查询中都使用了别名,是因为当内部查询引用外部查询中的列,或者外部查询引用内部查询中的列时必须需要别名。

4 总结

相关子查询,可以理解为2层循环,要想执行内层的查询,需要先从外层查询到1个值出来。执行的顺序是,父查询1个值,子查询对这个得到的值进行1轮查询,总查询次数是m*n,在使用相关子查询时,要合理的利用Select和Where在相关子查询中的应用,另外相关子查询将极大地降低数据检索的速度,对于拥有几百万个行但没有索引的大型表的非选择性查询更是如此,并尽可能地避免使用相关子查询。

参考文献:

[1]葛宇锋. MongoDB查询优化技术研究[D].南京邮电大学,2017.

[2]毛思语,张利军,张小芳,高锦涛,李战怀.面向分布式数据库的相关子查询优化策略[J].华东师范大学学报(自然科学版),2016(05):56-66.

[3]王千阁,何蒲,聂铁铮,申德荣,于戈.区块链系统的数据存储与查询技术综述[J].计算机科学,2018,45(12):12-18.

[4]李斌,向军文,李明建,罗群,胡博文,晋长昊.页岩气勘探中的空间关系型数据库设计[J].非常规油气,2019,6(02):111-116+90.

【通联编辑:王力】