博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅谈T-SQL中的子查询
阅读量:6446 次
发布时间:2019-06-23

本文共 2325 字,大约阅读时间需要 7 分钟。

引言

  这篇文章我们来简单的谈一下子查询的相关知识。子查询可以分为独立子查询和相关子查询。独立子查询不依赖于它所属的外部查询,而相关子查询则依赖于它所属的外部查询。子查询返回的值可以是标量(单值)、多值、或者整个表。下面来详细介绍子查询的相关内容。

独立子查询

  独立子查询是独立于外部查询的子查询。在逻辑上,独立子查询在执行外部查询之前只需要先执行一次,接着外部查询使用子查询的结果继续进行查询。请看下面的例子:

  假设现在需要返回Orders表中订单号最大的记录。通过标量子查询我们可以实现这个功能。

1 select orderid,orderdate,empid,custid2 from Sales.Orders3 where orderid=4         (select max(orderid) from Sales.Orders)
1 11077    2008-05-06 00:00:00.000    1    65

  我们看到11077是最大的订单号,通过子查询我们可以先查询出编号最大的订单号,让外部查询的OrderId与查询处理的最大的订单号相同即可。

  注意:对于标量独立子查询如果返回多个值SQL语句会报错,因为在WHERE子句中,我们使用的是等号,等号与多个值进行比对时,会出错。

独立多值子查询

  前面提到,对于标量子查询,子查询返回的结果只能是单值。独立多值子查询是可以返回多个值的子查询。IN谓词可以处理独立多值子查询。IN谓词的匹配规则是:如果标量表达式的值与子查询返回值中的任何一个值相等,IN谓词的计算结果就是TRUE。下面我们还是通过一个例子来了解下:

  假设我们现在需要返回有雇员名称是D开头的处理的订单。通过独立多值子查询我们可以这样写:

1 select orderid,orderdate,empid,custid2 from Sales.Orders3 where empid in4     (select empid from HR.Employees5         where lastname like 'D%')

  我们看到,相关多值子查询先查询Employees表,找出所有已D开头的雇员,形成一个结果集。然后外部查询在查询每一行时都会将数据与该结果集进行匹配,如果发现empid是在子查询中的结果集中,就返回该行。当然,我们也可以通过内连接来达到同样的目的。

1 select orderid,orderdate,O.empid,custid2 from Sales.Orders as O3     inner join HR.Employees as E4     on O.empid=E.empid5 where lastname like 'D%'

  注意:在子查询返回的结果集中,应该排除NULL值

相关子查询

  相关子查询是引用了外部查询中出现的表的列的子查询。在逻辑上,子查询会为每一个外部行单独计算一次。请看下面的例子:

  假设,现在需要返回每一个客户的最大的订单号,使用相关子查询我们可以实现这样的功能。

1 select custid,orderid,orderdate,empid2 from Sales.Orders as O13 where orderid=4     (select max(orderid) from Sales.Orders as O25         where O1.custid=O2.custid)

  我们来理一下这个查询的逻辑过程。前面说过对于外部查询的每一行,相关子查询都会重新计算一次。对于外部查询的每一行,相关子查询都会根据外部行的客户ID来获取其最大的订单号,如果当前外部行的订单号与相关子查询返回的订单号匹配,就返回这一行,否则就丢弃这一行,进行下一行的匹配。

EXISTS谓词

  SQL支持一个名为EXISTS的谓词,它的输入是一个子查询,如果子查询能够返回任何行,EXIST就会返回TRUE,否则返回FALSE。下面还是通过一个例子来看吧

  假设现在需要查询下过订单的西班牙客户,SQL语句我们可以这样写:

1 select custid,companyname from Sales.Customers as C2 where country=N'Spain'3 and exists4     (select custid from Sales.Orders as O5         where O.custid=C.custid)

  在这个查询中,外部查询先筛选出西班牙的客户,然后将每一行与子查询进行匹配,如果该客户曾经下过订单就保留,否则过滤掉该行。

高级子查询

  下面介绍一些使用子查询来实现的叫高级的内容。读者可以选读。

  返回前一个或者后一个记录

  如果我们需要查询订单表,对于每一个订单返回其前一个订单级及后一个订单。在订单表中,"前一个"在概念上是指逻辑顺序,"前一个"指的是小于当前值的最大值。"后一个"值的是大于当前值的最小值。我们先来看实现前一个效果的SQL语句。

1 select orderid,orderdate,empid,custid,2     (select max(orderid) from Sales.Orders as O23         where O2.orderid

  结果如下:

  

转载于:https://www.cnblogs.com/dreamGong/p/5038980.html

你可能感兴趣的文章
转:如何将 Java 项目转换成 Maven 项目
查看>>
YACEP相关技术工具服务技巧(上)
查看>>
《AngularJS开发下一代Web应用》读书笔记与感想
查看>>
URAL 2034 Caravans(变态最短路)
查看>>
正向代理到指定泛域名的nginx配置
查看>>
mac版微信web开发者工具(小程序开发工具)无法显示二维码 解决方案
查看>>
wordcloud + jieba 生成词云
查看>>
关于“代码规范”,“Review”和“Check list”
查看>>
Xcode导入第三方库图文
查看>>
第八章 函数
查看>>
MySQL快速入门
查看>>
个人vim配置
查看>>
Ubuntu 14.04 mame sound fix
查看>>
修改mysql的root密码
查看>>
Spring Boot系列——如何集成Log4j2
查看>>
对称加密实现重要日志上报Openresty接口服务
查看>>
10. Regular Expression Matching
查看>>
C# 实现天气预报
查看>>
ios中键盘处理(二)
查看>>
从1.5k到18k, 一个程序员的5年成长之路
查看>>