SQL Server 子查询

子查询
  子查询本质上是嵌套进其他SELECT,UPDATE,INSERT,DELETE语句的一个被限制的SELECT语句,子查询也可以嵌套在其他子查询里面,这个嵌套最多可以达32层。子查询也叫 内部查询或者 内部选择,而包含子查询的查询语句也叫 外部查询外部选择
通常来讲,子查询按照子查询返回的数据的类型,可分为3种,分别为:
1.返回一张数据表(Table)    --数据源
2.返回一列值(Column)    --选择条件
3.返回单个值(Scalar)        --计算列

 

子查询作为数据源使用
  嵌套在SQL语句中的FROM子句之后,亦可以被JOIN子句链接,此时子查询返回一个表,作为数据源的形式使用,可以看成为视图(VIEW),临时存在,不包含在数据库中。 注意:作为数据源被使用时,需要加上表别名
SELECT * FROM (SELECT column1,column2,.., FROM table_name) AS v

SELECT * FROM table_A a
INNER JOIN (SELECT column1,column2,.. FROM table_b) b ON a.column1 = b.column1
作为数据源使用是子查询里面最简单的运用,在这之前,子查询分为 相关子查询无关子查询,在下面会讲到

 

子查询作为选择条件使用
作为选择条件的子查询也是先对比较复杂的运用,返回值为一列,即使是单个值也会被看成一行一列
SELECT * FROM table_A  
WHERE column1 IN (SELECT column1 FROM table_B WHERE column2 IS NOT NULL) 
在上面的语句中,IN子句嵌套的子查询语句返回一列,所以作为 外部查询选择条件来被使用

 

IN与NOT IN
IN和NOT IN最好不要频繁使用,对于数据量小的查询当然没问题,但对于数据量大的查询,这种执行效率是很低的,原因是IN和NOT IN并不是针对索引的,而且会引发很多潜在性的问题。但是存在即合理,只有IN里面是固定值的话,才可以使用。
SELECT * FROM table_A WHERE column1 IN ('A','B')
只有在上面这种情况下使用IN和NOT IN才是安全的,其他情况下,最好使用EXISTS,NOT EXISTS,JOIN关键字来替代,除了IN之外,用于选择条件的关键字还有ANY和ALL,这两个关键字和其字面上的意思一样,配合运算符一起使用‘>’‘<’等
SELECT * FROM table_A 
WHERE column1 =ANY (SELECT column1 FROM table_B WHERE column2 IS NOT NULL)
作为ANY和ALL配合运算符的使用,所实现的效果如下:

=ALL关键字很少使用,这个的效果在子查询中如果只有一个返回值,则和‘=’效果一样,而如果有多个返回值,结果为空

 

相关子查询和EXISTS关键字

上面所说的子查询都是无关子查询,子查询中还有一种很重要的查询是相关子查询,也叫重复子查询,比如,还是上面那个查询,用相关子查询来写:

SELECT * FROM table_A a
WHERE EXISTS (SELECT * FROM table_B b WHERE a.column1=b.column1 AND column2 IS NOT NULL)

查询的结果是和IN关键字的效果是一样的,那么如何区分相关子查询和无关子查询呢?最简单的方法就是直接看子查询本身是否可以执行,比如上面的子查询

SELECT * FROM table_B b WHERE a.column1=b.column1 AND column2 IS NOT NULL

高亮部分引用了外部查询的表,所以单独执行会报错

对于无关子查询来说,整个查询过程可分为,子查询只执行一次,然后交给外部查询

对于相关子查询来说,整个查询过程可分为,外部查询执行一次,内部查询就查询一次,依赖外部查询的次数,所以这也是被叫作重复子查询的原因,比如拿上面的相关子查询的例子来说:

SELECT * FROM table_A a 
WHERE EXISTS (SELECT * FROM table_B b WHERE a.column1=b.column1 AND column2 IS NOT NULL)

step1:执行外部查询SELECT * FROM table_A a,此时查询了第1条数据,column为1(打比方)

step2:执行内部查询SELECT * FROM table_B b  WHERE a.1 = b.column AND column2 IS NOT NULL,如果table_B中存在column1为1的数据,则返回true,否则false

step3:执行WHERE子句,返回结果为true的数据

step4:执行下一次循环,回到步骤1,此时查询了第2条数据,column2为2,重复以上步骤,直至结束

 

子查询作为计算列使用

当子查询作为计算列使用时,只返回单值,用在SELECT语句之后,同样也分为无关子查询与相关子查询

相关子查询的例子有:

SELECT column1,(SELECT column2 FROM table_B b where a.column1=b.column1) AS column2 FROM table_A a

当子查询作为计算列使用时,且为相关子查询时,会针对外部查询的每一行,返回唯一的值。

当子查询作为计算列使用时,且为无关子查询时,则只会一次性返回一个相同值

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值