[SQL必知必会学习] 06 子查询

 

关联子查询与非关联子查询

关联子查询:子查询的执行与主查询相关,需执行多次

非关联子查询:子查询的执行与主查询执行无关,只需执行一次

想要知道哪个球员的身高最高, 最高身高是多少, 就可以采用子查询的方式:

SELECT player_name, height FROM player WHERE height = (SELECT max(height) FROM player);

16846478-4c83fa8e58139f72.png

球员的身高最高.png

通过 SELECT max(height) FROM player,可以得到最高身高这个数值,通过最高身高2.16在player 这个表中可以查询到谁具有这个身高,属于非关联子查询

如果子查询的执行依赖于外部查询, 通常情况下都是因为子查询中的表用到了外部的表, 并进行了条件关联, 因此每执行一次外部查询, 子查询都要重新计算一次, 这样的子查询就称之为关联子查询。

要查找每个球队中大于平均身高的球员有哪些, 并显示他们的球员姓名、身高以及所在球队 ID

SELECT player_name, height, team_id FROM player AS a 
WHERE height > (SELECT avg(height) FROM player AS b WHERE a.team_id = b.team_id);

16846478-f27b37e48701436d.png

大于平均身高的球员.png

SELECT avg(height) FROM player AS b WHERE a.team_id = b.team_id 子查询依赖于外部查询(a.team_id = b.team_id)

子查询关键字

EXIST 子查询

EXIST 子查询用来判断条件是否满足, 满足的话为True, 不满足为 False。NOT EXIST 就是不存在的意思。

SELECT player_id, team_id, player_name FROM player 
WHERE EXISTS (SELECT player_id FROM player_score WHERE player.player_id = player_score.player_id);

16846478-78dbf2f2fa1fcdba.png

是否出场.png

集合比较子查询

与另一个查询结果集进行比较, 我们可以在子查询中使用IN、 ANY、 ALL和 SOME 操作符

IN判断是否在集合中
ANY与比较操作符一起使用,与子查询返回的任何值做比较
ALL与比较操作符一起使用,与子查询返回的所有值做比较
SOME实际上是ANY的别名,作用相同,一般常使用ANY
SELECT player_id, team_id, player_name FROM player WHERE player_id in (SELECT player_id FROM player_score WHERE player.player_id = player_score.player_id);

16846478-54c40ec6ceaec4ff.png

是否出场.png

期查询结果和使用EXISTS结果一样

可抽象两种模式为:

SELECT * FROM A WHERE cc IN (SELECT cc FROM B)

SELECT * FROM A WHERE EXIST (SELECT cc FROM B WHERE B.cc=A.cc)

如果表 A 比表 B 小, 那么IN子查询的效率要比EXIST 子查询效率高, 因为这时 B 表中如果对 cc 列进行了索引, 那么 IN 子查询的效率就会比较高。同样, 如果表 A 比表 B 大, 那么使用EXIST 子查询效率会更高, 因为我们可以使用到 A 表中对 cc列的索引,而不用从 B 中进行 cc 列的查询。

SELECT player_id, player_name, height FROM player WHERE height > ALL (SELECT height FROM player WHERE team_id = 1002);

16846478-fa41cb1bf6af68b2.png

image.png

将子查询作为计算字段

SELECT team_name, (SELECT count(*) FROM player WHERE player.team_id = team.team_id) AS player_num FROM team;

16846478-0841afedd6cc403c.png

image.png

16846478-4db9920773b09445.png

子查询.png

参考资料:

注:
练习数据库使用 SQL必知必会专栏(极客时间)中的作者提供的 王者荣耀数据库以及NBA数据库
练习系统 MySQL Server version: 5.7.26-0ubuntu0.16.04.1 (Ubuntu)

极客时间 SQL必知必会学习

SQL必知必会专栏(极客时间)链接:
http://gk.link/a/103Sm

《MySQL必知必会》学习笔记(9-14):

https://www.jianshu.com/p/6db64562d2c6

此篇内容:用正则表达式进行搜索、创建计算字段、使用数据处理函数、汇总数据、分组数据、使用子查询


GitHub链接:
https://github.com/lichangke/LeetCode

知乎个人首页:
https://www.zhihu.com/people/lichangke/

简书个人首页:
https://www.jianshu.com/u/3e95c7555dc7

个人Blog:
https://lichangke.github.io/

欢迎大家来一起交流学习

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

墨1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值