sql之独立子查询和相关子查询总结

1、独立子查询:顾名思义:就是子查询和外层查询不存在任何联系,是独立于外层查询的:

下面就看一个例子:

有一张订单表 Sales.Order 和一张 客户表 Sales.Customer

下面的sql 语句是为了查询出Sales.Customer里 custid(用户id)不在 Sales.Order 的custid

1 select custid 
2 from [Sales.Customers]
3 where custid not in 
4 (
5   select custid 
6   from [Sales.Orders]
7 ) 

2、相关子查询:顾名思义:就是子查询里面的条件依赖于外层查询的数据

下面我再来举一个例子:

业务要求:查询出每个客户的订单的数量:

1 select distinct custid,
2  (
3    select COUNT(*)
4    from [Sales.Orders] 
5    --相关子查询:依赖于外层查询结果;;是外层和内层相互结合的操作
6    where [Sales.Orders].custid=[Sales.Customers].custid
7  ) as orderNum
8 from [Sales.Customers]

查询的结果:

所以我们不难看出:相关子查询比独立子查询实现的功能强大的多

3、下面我再来介绍一下 exists 的使用(个人认为:这个有时好用但是有时也很不好用)

业务要求:这里要用到一张表 供应商表([Production.Supplier]),查询出 客户表中的 公司名称companyname 不再[Production.Supplier] 里的 数据

使用独立子查询实现:

1 select distinct companyname
2 from [Sales.Customers]
3 where companyname not in
4 (
5   select distinct companyname from [Production.Supplier]
6 )

使用相关子查询:

select distinct companyname
from [Sales.Customers]
     --exists:是否存在
where not exists
    (
     select companyname  from [Production.Supplier]
     --这个是对于 每一次查询出的 外层数据 在 子查询里面进行使用
     where [Production.Supplier].companyname = [Sales.Customers].companyname
    )

我们可以看出使用下面的相关子查询,并且使用到了exists ,反而很复杂,所以大家可以根据业务自己做判断。

3、高级子查询

1、业务要求:查询出 order 表面的orderid 以及其 对应的 相邻的前面的和相邻的后面的 orderid(注意由于是订单表,可能前后的订单之间的大小并不是相差1):使用相关子查询:

 1 select  orderid,
 2 (
 3    select MAX(orderid)
 4    from [Sales.Orders] as innerOrder
 5    where innerOrder.orderid<outerOrder.orderid
 6 ) as primerOrderId,
 7 (
 8   select MIN(orderid)
 9   from [Sales.Orders] as innerOrder
10   where innerOrder.orderid > outerOrder.orderid
11   
12 ) as lastOrderId
13 from [Sales.Orders] as outerOrder

2、连续聚合(使用相关子查询)

业务要求:对orderid实现 累加的结果作为一个查询字段进行输出

1 select orderid,
2 (
3    select SUM(orderid)
4    from [Sales.Orders] as innerOrder
5    where innerOrder.orderid<=outerOrder.orderid
6 ) as totalOrderId
7 from [Sales.Orders] as outerOrder

查询效果:

原文地址:https://www.cnblogs.com/xiaoxiaogogo/p/sql.html