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

1、独立子查询:顾名思义:就是子查询和外层查询不存在任何联系,是独立于外层查询的:
下面就看一个例子:
有一张订单表 Sales.Order 和一张 客户表 Sales.Customer
下面的sql 语句是为了查询出Sales.Customer里 custid(用户id)不在 Sales.Order 的custid

select custid 
from [Sales.Customers]
where custid not in
(
select custid
from [Sales.Orders]
)

2、相关子查询:顾名思义:就是子查询里面的条件依赖于外层查询的数据
下面我再来举一个例子:
业务要求:查询出每个客户的订单的数量:

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

查询的结果:

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

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

3、下面我再来介绍一下 exists 的使用(个人认为:这个有时好用但是有时也很不好用)
业务要求:这里要用到一张表 供应商表([Production.Supplier]),查询出 客户表中的 公司名称companyname 不再[Production.Supplier] 里的 数据
使用独立子查询实现:

select distinct companyname
from [Sales.Customers]
where companyname not in
(
select distinct companyname from [Production.Supplier]
)

使用相关子查询:

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):使用相关子查询:

 select orderid, 
(
select MAX(orderid)
from [Sales.Orders] as innerOrder
where innerOrder.orderid<outerOrder.orderid 
) as primerOrderId, 
( 
select MIN(orderid) 
from [Sales.Orders] as innerOrder
where innerOrder.orderid > outerOrder.orderid
 ) as lastOrderId
from [Sales.Orders] as outerOrder

2、连续聚合(使用相关子查询)
业务要求:对orderid实现 累加的结果作为一个查询字段进行输出

select orderid,
(
select SUM(orderid)
from [Sales.Orders] as innerOrder
where innerOrder.orderid<=outerOrder.orderid
) as totalOrderId
from [Sales.Orders] as outerOrder

查询效果:

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

    原文作者:萬惡的Nickey
    原文地址: https://www.jianshu.com/p/eeba81e8b06c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞