数据库学习笔记:嵌套子查询(非相关子查询)和相关子查询

背景:
在学习sql的时候,我很在意一个sql的执行顺序,在上面一篇数据库学习笔记中有记录;
在学到子查询的时候,本来就是感觉很简单,优先执行子查询,即括号里面的查询,用返回的值再执行主查询即可,先看下下面两个表。

部门表departments
部门表department
员工表employees
员工表employees

题目:sql要求查询出各个部门的员工数,部门中没有员工的则员工数为0
首先想到的是直接是使用外连接和group by,但是外连接当部门没有员工时,count()出来的结果也是1,不过可以用if(emploees.emploee_id is null,0,count())解决。所以有后面的子查询方法

下面是使用子查询的方法:

#用于统计各个部门中的员工数
SELECT d.*,(SELECT COUNT(*) FROM employees e WHERE e.department_id=d.department_id) FROM  departments d;

执行结果:
在这里插入图片描述

这个sql中有两个疑惑:
1、首先不能单独地执行子查询,因为涉及到了主查询中的一个表
所以按照之前的逻辑,我把它提取出来,改变了成了连接查询的方式

#子查询
SELECT COUNT(*) FROM employees e WHERE e.department_id=d.department_id
#改成连接查询
SELECT COUNT(*) FROM employees e,department d WHERE e.department_id=d.department_id

但是很明显,这个查询结果是一个标量,只有一个值,放到主查询中并不能实现按部门分别统计的效果,为什么整个查询可以实现按部门统计呢?

2、在连接查询中如果结果为空,count()会是1,那么这种查询结果如果为空,count()出来是1还是0呢。

通过网上查询,了解到了子查询有两种:

嵌套子查询(非相关子查询)相关子查询

直接复制一下概念:
子查询:嵌套在其他查询中的查询称之。
子查询又称内部,而包含子查询的语句称之外部查询(又称主查询)。
所有的子查询可以分为两类,即相关子查询和非相关子查询

  1. 非相关子查询是独立于外部查询的子查询,子查询总共执行一次,执行完毕后将值传递给外部查询。
  2. 相关子查询的执行依赖于外部查询的数据,外部查询执行一行,子查询就执行一次。
    故非相关子查询比相关子查询效率高

嵌套子查询的执行不依赖与外部的查询
执行过程
(1)执行子查询,其结果不被显示,而是传递给外部查询,作为外部查询的条件使用。
(2)执行外部查询,并显示整个结果。  
嵌套子查询一般可以分为:返回单值的子查询 和 返回一个列表的子查询

相关子查询的执行依赖于外部查询。
多数情况下是子查询的WHERE子句中引用了外部查询的表,外部查询执行一行,子查询就执行一次。
执行过程
(1)从外层查询中取出一个元组,将元组相关列的值传给内层查询。
(元组的概念:元组是关系数据库中的基本概念,关系是一张表,表中的每行(即数据库中的每条记录)就是一个元组,每列就是一个属性。 在二维表里,元组也称为记录
(2)执行内层查询,得到子查询操作的值。
(3)外查询根据子查询返回的结果或结果集得到满足条件的行。
(4)然后外层查询取出下一个元组重复做步骤1-3,直到外层的元组全部处理完毕

所以题目中的sql的执行过程:
(1)从外层查询即departments表中取出第一行,把值传给内层查询
在这里插入图片描述
(2)执行内层查询,得到子查询操作的值。对查询的数据进行计数count(*),此时若查询不到则计数结果为0。
(3)外查询根据子查询返回的结果或结果集得到满足条件的行。这是就相当于departments表中的第一个department_id计数完毕,返回结果。
(4)然后外层查询取出下一个行,重复做步骤1-3,直到employees表中所有行循环完毕。

总结:
相关子查询的执行依赖于外部查询。多数情况下是子查询的中引用了外部查询的表,外部查询执行一行,子查询就执行一次。

有时候很多东西似懂非懂,好像能理解但是又弄不清其中的道理,这种感觉就很难受,而且也会影响后续的学习,给自己挖下一个坑,但是感觉自己确实已经有不少坑等着填了。。。

参考资料转载自:
https://blog.csdn.net/qq_39930129/article/details/80112884?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.channel_param

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值