员工表的主要信息:

需求:检索工资大于同职位的平均工资的员工信息。

直觉的做法

员工多,而相应的职位(如销售员、经理、部门经理等)少,因此首先想到的思路是对职位分组,这样就能分别得到各个职位的平均工资,再比较每个人的工资和他对应职位的平均工资,大于平均工资则被筛选出来。

1.首先得到各个职位的平均工资

代码如下:

select job,avg(sal) from emp group by job;

结果如下:

2.然后利用子查询,对他们进行对比(幻想)

1 select * from emp where sal >
2 (select avg(sal) from emp
3 group by job);

但是子表查询结果是5行,因此这段代码根本无法执行。

正确的做法是使用关联子查询

1 select * from emp e where sal >
2 (select avg(sal) from emp where job = e.job);

执行逻辑是这样

第一步

先执行外层查询,即先执行:

select * from emp e;

结果是:

也就是该表的所有内容。又因为子查询中连接了这个表本身(where job = e.job ),所以将第一条记录转到子查询。

第二步

这条进入子查询后,子查询job是CLERK,所以先筛选出所有Job=‘CLERK’的,再对他们取平均。

相当于执行了:

select avg(sal) from emp where job='CLERK';

结果是:

第三步

这个结果进入外层查询where和SMITH这个人的sal进行对比,相当于执行了

select * from emp where sal>1037.5 and job='CLERK';

结果是:

循环

然后就抽出第一次外层查询的第二条(ALLEN):

继续如上第一、二、三步。

会重复计算吗?

每条记录都执行,第二行的ALLEN和第三行的WARD都是SALESMAN(销售人员),那么他们在子查询中会重复计算一次平均工资进行比较。这样会不会设计重复计算?答案是不会,效率并没有降低,SQL已经对此进行过优化。

总结

关联子查询(相关子查询),其特性是能够把主查询的值传递给子查询。

示例:找到员工表中薪水大于本部门平均薪水的员工

首先想到的思路是:通过子查询查询部门的平均薪水,然后主查询的薪水大于查询出来的平均薪水即可,如下:

select empno,ename,sal
from emp
where sal > (select avg(sal) from emp where deptno =?)

上面的?处应该是每次主查询的部门,比如主查询是查询销售部的数据,那是更销售部的平均薪水进行对比才对啊。

关联子查询就是解决这个问题的,可以把主查询的deptno传给子查询,那就能够跟本部门平均薪水对比,如下:

select empno,ename,sal,(select avg(sal) from emp where deptno =e.deptno) as avgsal
from emp e
where sal > (select avg(sal) from emp where deptno =e.deptno)

来源于:https://www.cnblogs.com/heenhui2016/p/10574695.html

一文让你彻底理解SQL关联子查询的更多相关文章

  1. 如何正确理解SQL关联子查询

    一.基本逻辑 对于外部查询返回的每一行数据,内部查询都要执行一次.在关联子查询中是信息流是双向的.外部查询的每行数据传递一个值给子查询,然后子查询为每一行数据执行一次并返回它的记录.然后,外部查询根据 ...

  2. 一文让你彻底理解SQL的子查询

    什么是子查询 当一个查询是另一个查询的条件时,称之为子查询. 为什么要使用子查询 在SELECT.INSERT.UPDATE或DELETE命令中只要是表达式的地方都可以包含子查询,子查询甚至可以包含在 ...

  3. SQL关联子查询

    SQL关联子查询执行顺序: 1.先取到主查询中的相关数据,一次取一行主查询的数据 2.然后传入子查询,进行子查询 3.最后做主查询where筛选,注意子查询的where条件同样需要加在主查询后 参考: ...

  4. SQL进阶系列之6用关联子查询比较行与行

    写在前面 使用SQL对同一行数据进行列间的比较很简单,只需要在WHERE子句里写上比较条件就可以了,对于不同行数据进行列间比较需要使用自关联子查询. 增长.减少.维持现状 需要用到行间比较的经典场景是 ...

  5. mssql sql高效关联子查询的update 批量更新

    /* 使用带关联子查询的Update更新     --1.创建测试表 create TABLE Table1     (     a varchar(10),     b varchar(10),   ...

  6. SQL基础教程(第2版)第5章 复杂查询:5-3 关联子查询

    第5章 复杂查询:5-3 关联子查询 ● 关联子查询会在细分的组内进行比较时使用.● 关联子查询和GROUP BY子句一样,也可以对表中的数据进行切分.● 关联子查询的结合条件如果未出现在子查询之中就 ...

  7. SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句

    SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...

  8. 神奇的 SQL 之子查询,细节满满 !

    前言 开心一刻 有一天,麻雀遇见一只乌鸦. 麻雀问:你是啥子鸟哟 ? 乌鸦说:我是凤凰. 麻雀说:哪有你龟儿子这么黢黑的凤凰 ? 乌鸦说:你懂个铲铲,老子是烧锅炉的凤凰. 子查询 讲子查询之前,我们先 ...

  9. 利用带关联子查询Update语句更新数据

    Update是T-sql中再简单不过的语句了,update table set column=expression  [where condition],我们都会用到.但update的用法不仅于此,真 ...

随机推荐

  1. 08-SpringCloud Consul

    Consul简介 官网 Consul下载地址 What is Consul? Consul is a service mesh solution providing a full featured c ...

  2. STM32—时钟树(结合系统时钟函数理解)

    时钟树的概念: 我们可以把MCU的运行比作人体的运行一样,人最重要的是什么?是心跳! 心脏的周期性收缩将血液泵向身体各处.心脏对于人体好比时钟对于MCU,微控制器(MCU)的运行要靠周期性的时钟脉冲来 ...

  3. hdmi 随笔

    从图片来看,每张图片开始传输的是45像素的垂直同步, 1.控制数据贯穿所有时间,没个不是控制数据的传输都被控制数据包围.控制数据还要通过控制位指示,下一个数据是数据岛还是视频信号. 2.terc4 全 ...

  4. 题解 God Knows

    传送门 这里有个线段树维护单调栈的神仙技巧 同机房dalao @Yubai的不同理解方式 yysy,我考场上连\(n^2\)的暴力都没搞出来 这里实际上求的是最小权极大上升子序列 但这个跟题目几乎没什 ...

  5. 项目报错:Invalid bound statement (not found):

    出现这种错误有好多种情况,常见的错误有以下这些: 1.检查xml文件所在package名称是否和Mapper interface所在的包名 <mapper namespace="com ...

  6. VirtualBox-虚拟硬盘扩容-win7

    问题: 我在VirtualBox下搭建的win7系统只设置了一个C盘,当初只给硬盘分配32G,如今深受生活的毒打,发现只剩5G可用,装个PS都费劲. 我要扩容,扩容! 当前环境: VirtualBox ...

  7. ASP.NET Core教程:使用Supervisor做ASP.NET Core应用程序守护进程

    一.前言 在上一篇文章中,我们讲解了如何在Linux服务器上面部署ASP.NET Core应用程序,并且使用Nginx作为反向代理.我们在Linux服务器上面,是通过ASP.NET Core自宿主的方 ...

  8. 【mysql】索引优化分析

    1. 索引的概念 1.1 索引是什么 MySQL 官方对索引的定义为:索引(Index)是帮助MySQL 高效获取数据的数据结构.可以得到索引的本质:索引是数据结构.可以简单理解为排好序的快速查找数据 ...

  9. Spring第一课:核心API(三)

    以上是Spring的核心部分,其中需要了解的是:BeanFactory.ApplicationContext[FileSystemXmlApplicationContext.ClassPathXmlA ...

  10. VS code快速创建vue模板

    忘记了.vue文件的格式或者不想手动敲那段模板代码怎么办?VS code快速创建vue模板帮你偷个小懒 第一步:新建模板并保存 打开 VS code,依次点击 file > Preference ...