如何正确理解SQL关联子查询
一、基本逻辑
对于外部查询返回的每一行数据,内部查询都要执行一次。在关联子查询中是信息流是双向的。外部查询的每行数据传递一个值给子查询,然后子查询为每一行数据执行一次并返回它的记录。然后,外部查询根据返回的记录做出决策。
反正我是没看懂,下面详细解释SQL中关联子查询的逻辑。
二、举例
员工表的主要信息:

要解决的问题:检索工资大于同职位的平均工资的员工信息。
2.1 直觉的做法
员工多,而相应的职位(如销售员、经理、部门经理等)少,因此首先想到的思路是对职位分组,这样就能分别得到各个职位的平均工资,再比较每个人的工资和他对应职位的平均工资,大于则被筛选出来。
首先得到各个职位的平均工资
代码如下:
select job,avg(sal) from emp
group by job;
结果如下:

然后利用子查询,对他们进行对比(幻想)
代码如下:
select * from emp where sal >
(select avg(sal) from emp
group by job);
但是子表查询结果是5行,因此这段代码根本无法执行。
2.2 正确的做法
正确的做法是使用关联子查询。代码如下。
select * from emp e where sal >
(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已经对此进行过优化。
如何正确理解SQL关联子查询的更多相关文章
- 一文让你彻底理解SQL关联子查询
员工表的主要信息: 需求:检索工资大于同职位的平均工资的员工信息. 直觉的做法 员工多,而相应的职位(如销售员.经理.部门经理等)少,因此首先想到的思路是对职位分组,这样就能分别得到各个职位的平均工资 ...
- SQL关联子查询
SQL关联子查询执行顺序: 1.先取到主查询中的相关数据,一次取一行主查询的数据 2.然后传入子查询,进行子查询 3.最后做主查询where筛选,注意子查询的where条件同样需要加在主查询后 参考: ...
- 一文让你彻底理解SQL的子查询
什么是子查询 当一个查询是另一个查询的条件时,称之为子查询. 为什么要使用子查询 在SELECT.INSERT.UPDATE或DELETE命令中只要是表达式的地方都可以包含子查询,子查询甚至可以包含在 ...
- SQL进阶系列之6用关联子查询比较行与行
写在前面 使用SQL对同一行数据进行列间的比较很简单,只需要在WHERE子句里写上比较条件就可以了,对于不同行数据进行列间比较需要使用自关联子查询. 增长.减少.维持现状 需要用到行间比较的经典场景是 ...
- mssql sql高效关联子查询的update 批量更新
/* 使用带关联子查询的Update更新 --1.创建测试表 create TABLE Table1 ( a varchar(10), b varchar(10), ...
- SQL基础教程(第2版)第5章 复杂查询:5-3 关联子查询
第5章 复杂查询:5-3 关联子查询 ● 关联子查询会在细分的组内进行比较时使用.● 关联子查询和GROUP BY子句一样,也可以对表中的数据进行切分.● 关联子查询的结合条件如果未出现在子查询之中就 ...
- 神奇的 SQL 之子查询,细节满满 !
前言 开心一刻 有一天,麻雀遇见一只乌鸦. 麻雀问:你是啥子鸟哟 ? 乌鸦说:我是凤凰. 麻雀说:哪有你龟儿子这么黢黑的凤凰 ? 乌鸦说:你懂个铲铲,老子是烧锅炉的凤凰. 子查询 讲子查询之前,我们先 ...
- SQL Fundamentals: 子查询 || WHERE,HAVING,FROM,SELECT子句中使用子查询,WITH子句
SQL Fundamentals || Oracle SQL语言 子查询(基础) 1.认识子查询 2.WHERE子句中使用子查询 3.在HAVING子句中使用子查询 4.在FROM子句中使用子查询 5 ...
- 利用带关联子查询Update语句更新数据
Update是T-sql中再简单不过的语句了,update table set column=expression [where condition],我们都会用到.但update的用法不仅于此,真 ...
随机推荐
- 微信小程序添加背景图片的坑
给微信小程序页面加载背景图片解决方案 直接附上原文地址: 给微信小程序页面加载背景图片解决方案 - YUSIR 完美CODING世界 - CSDN博客 https://blog.csdn.net/y ...
- C#如何编写短信接口,以及接口的调用,包括C#.net访问web,并处理返回值的简例。
在系统的开发中我们经常会用到接口,下面给大家介绍一种短信接口的编写与调用. 我们常调用接口来完成一些信息的通知或者发送验证码,那么这些操作是如何完成的呢?来看一下详细的介绍吧! 首先呢,我们需要有一个 ...
- (排序EX)P1093 奖学金
题解: #include<iostream>using namespace std;int r=0;void swap(int &a,int &b){ int t=a; ...
- 【LeetCode】160. 相交链表
题目 输入两个链表,找出它们的第一个公共节点. 如下面的两个链表: 在节点 c1 开始相交. 示例 1: 输入:intersectVal = 8, listA = [4,1,8,4,5], listB ...
- java向python ,text文件动态传参或传值问题完美解决
由于业务需要对python文件进行参数传递,通过下面两个java方法完美解决此问题,我的思路是:首先我要先把上次写的参数删除,第二我要新的参数写到python文件中. 第一个方法解决了删除上次传递的参 ...
- Python学习——enumerate
enumerate(seq, start) seq -- 可遍历的序列 start -- 下标起始位置 seq = [11,22,33,44,55] for i in seq: print( ...
- Python风格规范分享
今天给大家分享Python 风格规范,以下代码中 Yes 表示推荐,No 表示不推荐. 分号 不要在行尾加分号, 也不要用分号将两条命令放在同一行. 行长度 每行不超过80个字符 以下情况除外: 长的 ...
- 2020/2/12 PHP编程学习
感冒终于差不多好了.. 学了一天的tp框架商城开发,到此,一个小商城算是开发完了,写一个简单小总结吧233 首先说的编程方面,其实并没有质的提升orz,怎么可能几天就有大突破233 不过收获还是有的, ...
- Vue v-bind
指令作用: 给元素的属性赋值 它是一个 vue 指令,用于绑定 html 属性 写法: 正常写法 <div v-bind:原属性名="变量||"常量""& ...
- c 循环左移
char b[11] = {'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; const int iShift = 4; for (int j = ...