引言

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

独立子查询

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

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

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

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

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

独立多值子查询

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

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

 select orderid,orderdate,empid,custid
from Sales.Orders
where empid in
(select empid from HR.Employees
where lastname like 'D%')

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

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

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

相关子查询

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

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

 select custid,orderid,orderdate,empid
from Sales.Orders as O1
where orderid=
(select max(orderid) from Sales.Orders as O2
where O1.custid=O2.custid)

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

EXISTS谓词

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

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

 select custid,companyname from Sales.Customers as C
where country=N'Spain'
and exists
(select custid from Sales.Orders as O
where O.custid=C.custid)

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

高级子查询

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

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

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

 select orderid,orderdate,empid,custid,
(select max(orderid) from Sales.Orders as O2
where O2.orderid<O1.orderid) as prevorderid
from Sales.Orders as O1

  结果如下:

  

浅谈T-SQL中的子查询的更多相关文章

  1. SQL中的子查询

    目录 WHERE子查询 HAVING子查询 FROM子查询 SELECT子查询 EXISIT子查询 查询薪资排名的员工信息(面试) z子查询就是将一个查询(子查询)的结果作为另一个查询(主查询)的数据 ...

  2. 在 SQL Server 数据库的 WHERE 语句中使用子查询

    这是关于子查询语句的一系列文章中的第三篇.在这篇文章中我们将讨论WHERE语句中的子查询语句.其他的文章讨论了其他语句中的子查询语句. 本次课程中的所有例子都是基于Microsoft SQL Serv ...

  3. SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  4. 工作中遇到的比较奇怪的一些sql(一些子查询)

    在列中进行子查询 1.在一个表中有多个员工ID,比如一个下单员工,一个修改订单的员工,可以使用在列中进行子查询,具体如下: ( SELECT staff_name FROM sp_staff_basi ...

  5. 浅谈oracle树状结构层级查询之start with ....connect by prior、level及order by

    浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...

  6. SQL Server 数据库子查询基本语法

    一.SQL子查询语句 1.单行子查询        select ename,deptno,sal        from emp        where deptno=(select deptno ...

  7. 浅谈oracle树状结构层级查询测试数据

    浅谈oracle树状结构层级查询 oracle树状结构查询即层次递归查询,是sql语句经常用到的,在实际开发中组织结构实现及其层次化实现功能也是经常遇到的,虽然我是一个java程序开发者,我一直觉得只 ...

  8. 详细讲述MySQL中的子查询操作 (来自脚本之家)

    继续做以下的前期准备工作: 新建一个测试数据库TestDB: ? 1 create database TestDB; 创建测试表table1和table2: ? 1 2 3 4 5 6 7 8 9 1 ...

  9. 在MySQL中使用子查询

    子查询作为数据源 子查询生成的结果集包含行.列数据,因而非常适合将它与表一起包含在from子句的子查询里.例: SELECT d.dept_id, d.name, e_cnt.how_many num ...

  10. SQL语句:子查询

    一,子查询定义: 子查询就是嵌套在主查询中的查询. 子查询可以嵌套在主查询中所有位置,包括SELECT.FROM.WHERE.GROUP BY.HAVING.ORDER BY. 但并不是每个位置嵌套子 ...

随机推荐

  1. 算法与数据结构之交换(SWAP)排序

    #include<stdio.h> #include<stdlib.h> void swap(int x,int y); void swap_p(int *px,int *py ...

  2. nhibernate 配置nvarchar(max)

     若你真的需要一个nvarchar(max)的sql存储空间时,记得增加 .CustomType("StringClob") Demo:Map(x => x.ContentM ...

  3. 【BZOJ-3573】米特运输 树形DP

    3573: [Hnoi2014]米特运输 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 1023  Solved: 604[Submit][Statu ...

  4. springMVC-配置Bean

    配置Bean - 配置形式:基于xml文件方式,基于注解的方式- bean的配置方式:通过全类名(反射),通过工厂方法(静态工厂方法和实例工厂方法),FactoryBean依赖注入的方方式,属性注入和 ...

  5. hdu 2857 求点关于线段的对称点

    本来很简单的一个题,但是有个大坑: 因为模板中Tline用到了直线的一般方程ax+by+c=0,所以有种很坑的情况需要特判: 斜率不存在啊喂 老子坑了一下午2333 #include <math ...

  6. POJ2195 Going Home

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 22091   Accepted: 11156 Description On ...

  7. ecshop /includes/modules/payment/alipay.php SQL Injection Vul

    catalog . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 ECSHOP支付插件存在SQL注入漏洞,此漏洞存在于/includes/ ...

  8. Linux下pdf阅读器推荐

    由于需要在pdf文件上做标记,所以自带的文档查看器根本满足了需求,之前去网上查了查,Okular评价挺高,就安装了一个,确实能基本满足我的需求,但是 1.界面感觉还是不太友好,书签栏一直在那. 2.而 ...

  9. org.springframework.expression.spel.SpelEvaluationException: EL1005E:(pos 0): Type cannot be found

    今天在完成Spring项目的时候遇到了一个类似于下面的异常: 10.03.2010 13:53:53 org.apache.catalina.core.StandardWrapperValve inv ...

  10. 我所了解的JavaScript糟粕和鸡肋

    糟粕 全局变量 众所周知,全局变量在很小的程序中可能会带来方便,但随着程序变得越来大,全局变量将难以处理,全局变量将降低程序的可靠性. 在js中有3种方式定义全局变量 脱离任何函数安排一个var语句  ...