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
查询效果: