子查询,也可以 So easy !
- 2020 年 1 月 2 日
- 筆記
本文标识 : MQ0010
本文编辑 : 长安月下赏美人儿
编程工具 : MySQL、DBeaver
阅读时长 : 7分钟
目录
前言
子查询定义
子查询分类
标量子查询
关联子查询
EXISTS 子查询
前言
小编第一次看到子查询这个词,也是懵圈的,后来细细想一想,子查询貌似和一道经典题目有关。
经典题目:把大象放进冰箱里,总共分几步?
经典回答:三步!
- 第一步,把冰箱门打开
- 第二步,把大象放进去
- 第三步,把冰箱门关上
看似逻辑清晰,一点儿毛病都没有!对不对!
但是,在数据分析过程中,却是大错特错!毕竟日常工作中,从A点走直线到B点的工作少之又少!
对于这道经典题目,如何科学又合理的回答?
- 首先,确认哪个冰箱(编号、体积、位置……)
- 其次,确认大象信息(物种、状态、重量……)
- 最后,确认无误,提取大象样本,入库关门
子查询定义
在SQL语言中,一个 SELECT-FROM-WHERE 语句称为一个查询块。当想捕捉的数据不能通过一个查询语句获得,必须经过多个步骤操作才能实现,这个时候就需要进行子查询。譬如,把非洲象左后腿切成宽度为1厘米的肉片,并将10公斤装入冰箱,这个过程即为子查询!
子查询分类
子查询有不同的分类标准,大致有3种,今天主要分享按功能划分的子查询信息。
1、子查询按功能划分
也可以说按照查询返回结果类型划分
(1)标量子查询:子查询返回结果是一个数据(一行一列)
(2)关联子查询:子查询返回结果非一行一列
- 列子查询:返回的结果是一列(一列多行)
- 行子查询:返回的结果是一行(一行多列)
- 表子查询:返回的结果是多行多列(多行多列)
(3)Exists子查询:返回的结果 1 或者 0
2、子查询按查询语句位置划分
(1)Where 子查询:子查询出现的位置在 where 条件中
(2)From 子查询:子查询出现的位置在 from 数据源中(做数据源)
3、子查询按语法结构来划分
(1)带有比较运算符的子查询
(sqlstatement) comparison(>,<,=,!=)
(2)带有 ANY(some) 或 ALL 谓词的子查询
comparison [ANY | ALL | SOME] (sqlstatement)
(3)带有谓词 IN 的子查询
expression [NOT] IN (sqlstatement)
(4)带有 EXISTS 谓词的子查询
[ NOT] EXISTS (sqlstatement)
标量子查询
标量子查询是指子查询返回的是单一值的标量,如一个数字或一个字符串,也是子查询中最简单的返回形式。
#子查询例1: SELECT GoodsID ,BarCode FROM demo.Goods WHERE CateID>(SELECT AVG(CateID) FROM demo.Goods);
数据结果:

#例 1 中子查询语句为: SELECT AVG(CateID) FROM demo.Goods; #例 1 中实际查询的语句为: SELECT GoodsID ,BarCode FROM demo.Goods WHERE CateID>925354677.1628;
子查询语句返回的是单一的数字(如下图)

有没有感觉很简单,唔,要不要来个刺激的!
要求:院校 A 即将开学,但是因为在职研究生,故年龄差异比较大。现在请求挑选出专业平均年龄比整体平均年龄大的专业的人的信息。听起来有些绕绕的,
逻辑解析:
(1)计算出各专业的平均年龄,即专业_avg_age
(2)计算出整体的平均年龄,即整体_avg_age
(3)提取 专业_avg_age>整体_avg_age 人员信息
#子查询例 2 : SELECT Profession ,AVG(Age) ,(SELECT AVG(age) FROMd emo.MemberInfo as avg_age) FROM demo.MemberInfo GROUP BY Profession HAVING AVG(Age)>(SELECT AVG(Age) FROM demo.MemberInfo);
数据结果:

其实,就是看着复杂,一一拆解开来,也是简单的!
标量子查询小结:
- 子查询语句返回为一行一列
- 当出现查询失败情况,首先观察子查询逻辑,并单独运行
- 子查询运行成功后,再进行外部查询,查看结果
关联子查询
关联子查询,是指子查询返回的结果并不是一行一列,可以是一行多列,一列多行,多行多列。
#关联子查询例 1 : SELECT MemberID ,Profession ,Sex FROM demo.MemberInfo as m3 WHERE Age>(SELECT AVG(age) FROM demo.MemberInfo as m2 WHERE m3.Profession=m2.Profession GROUP BY Profession);
数据结果:

逻辑解析:
(1)在表中找到你想要的字段块,即
SELECT MemberID ,Profession ,Sex FROM demo.MemberInfo as m3
(2)确定字段块精准的限制条件
SELECT AVG(age) FROM demo.MemberInfo as m2 GROUP BY Profession)
(3)两者建立连接,共同拥有的关键字为 Profession
WHERE m3.Profession=m2.Profession
关联子查询小结:
- 子查询语句返回多行数据信息
- 寻找前后连接点,即共同字段
EXISTS 子查询
EXISTS 子查询,是指子查询语句返回的信息中,如果外层查询的记录与子查询记录相匹配,则返回数据值。
#EXISTS 子查询例 1 : SELECT * FROM demo.Caregory as c WHERE EXISTS (SELECT * FROM demo.Goods as o WHERE o.CateID<921000100 AND c.CateID= o.CateID);
数据结果:

EXISTS 子查询小结:
- EXISTS 左侧无变量名、字段、列名
- EXISTS 右侧会关联一个子查询
- 子查询括号内为真即可
- 外层查询记录用于内层查询记录匹配