暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

从0到1学数据库:子查询

罗晓胜 2020-12-24
309

点击上方“罗晓胜”,马上关注,您的支持对我帮助很大

上期文章

 



/   前言   /


    前面其实我们已经接触过子查询了,一句话解释,子查询就是将 上一次查询的结果 作为 本次查询的原始数据(或是查询条件)。
    适用范围:当你的需求一次查询无法满足需求时(一次select找不到你要的数据,得多次查询),子查询所实现的功能,完全可以被多表联查代替,子查询能干的事,多表联查也能干。


/   正文   /


本章要点

• 子查询语法介绍
• 单行子查询
• 多行子查询
• 相关子查询
• EXISTS和NOT EXISTS操作符

子查询的基本语法

• 子查询的语法结构:SELECT 查询列 FROM 表名 WHERE 列名 操作符 (SELECT 查询列 FROM 表名);

• 括号内的查询叫做子查询(Subquery)或者内部查询(Inner Query),外面的查询叫做主查询(Main query)或外部查询 (Outer query)。

• 例 子查询当做条件示例

查询班级叫'一班'的所用用户
SELECT id, name, age, c_class
FROM student
WHERE c_class = (SELECT id FROM t_class WHERE name = '一班');

子查询注意事项

• 关于子查询,需要注意以下几点:– 子查询需要写在括号中;– 子查询需要写在运算符的右端;– 子查询可以写在WHEREHAVINGFROM子句中;– 子查询中通常不写ORDER BY子句。

子查询的种类

单行子查询(单列) 子查询返回的记录有且只有一条 多行子查询(单列) 子查询返回记录的条数可以是一条或多条 多列子查询 多列数据比较

单行子查询

• 单行子查询,子查询返回的记录有且只有一条。单行子查询要 求使用单行操作符,即: – >大于 – >= 大于等于 – < 小于 – <= 小于等于 – =等于 – <> 不等于

WHERE子句中单行子查询

• 例 查询所有为一班的学生

SELECT id, name, age, c_class
FROM student
WHERE c_class = (SELECT id FROM student WHERE name = '一班');

HAVING子句中单行子查询

• 除了在WHERE子句中外,也可以在HAVING子句中书写子查询。

• 例 查询学生班级总数大于平均班级号的班级和班级数

SELECT c_class,COUNT(c_class)
FROM student
GROUP BY c_class
HAVING COUNT(c_class) > (SELECT AVG(id) FROM t_class GROUP BY id);

多行子查询

• 多行子查询,子查询返回记录的条数可以是一条或多条。多行 子查询需要使用多行操作符。常用的多行操作符包括:

– IN – ANY – ALL

IN、ANY、ALL的使用

• IN操作符和以前介绍的功能一致,判断是否与子查询的任意一 个返回值相同。返回的结果可以是一条或多条。

• 例 多行子查询示例——IN操作符。

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a
WHERE a.c_class IN (SELECT b.id FROM t_class b where b.id = 1 or b.id =2);

• ANY:表示任意的。

– < ANY 比子查询返回的任意一个结果小即可,即小于返回结 果的最大值。– = ANY 和子查询中任意一个结果相等即可,相当于IN。– > ANY比子查询返回的任意一个结果大即可,即大于返回结 果的最小值。

• ALL:表示所有的。

– < ALL 比子查询返回的所有的结果都小,即小于返回结果的 最小值。– > ALL比子查询返回的所有的结果都大,即大于返回结果的 最大值。– = ALL 无意义,逻辑上也不成立。

• 例 ANY操作符。

SELECT a.id,a.name, a.age,a.c_class 
FROM student a
WHERE a.c_class > ANY (SELECT b.id FROM t_class b where b.id = 1 or b.id =2);

• 例 ALL操作符。

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a
WHERE a.c_class > ALL (SELECT b.id FROM t_class b where b.id = 1 or b.id =2);

多列子查询

显示名称和班级与班级表同名的用户

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a
WHERE (name, c_class) IN (SELECT name, id FROM t_class ) ;

子查询中空值问题

• 例7-14 子查询空值示例。

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a
WHERE a.c_class NOT IN (SELECT b.id FROM t_class b);

返回结果:未选定行

• 出现这种情况的原因有两个:– 子查询中返回值中包含有空值;– NOT IN操作符对空值不忽略。

• NOT IN操作符相当于<> ALL,即除了列表值的所有值,就包括了 空值NULL,结果即为空。

FROM语句中子查询

• 例 用子查询当做连接查询的另一张表

SELECT a.id,a.name, a.age ,a.c_class 
FROM student a , (SELECT id,name FROM t_class GROUP BY id) t
WHERE a.c_class = t.id ;

相关子查询

  • 不相关子查询:一条Sql语句中含有多条SELECT语句,先执行子查询,再执行外查询,子查询可对立运行

    • 关键字:(1)先子查询,再外查询 2)可以对立运行,即可以单独运行子查询,对外查询不干扰

  • 相关子查询:子查询不能独立运行,并且先运行外查询,再运行子查询

    • 关键字:(1)先外查询,再子查询 2)子查询不能独立运行

当子查询从一个在父查询涉及的表中引用一个列时,执行相关子查询。对于由父查询处理的每一行相关子查询都执行一次。相关子查询被用于 row-by-row 处理。对父查询的每一行,每个子查 询被执行一次

• 相关子查询中,内部查询需引用外部查询的列,进行交互判断。相关子查询的执行方式是一行行操作。外部查询每执行一行操 作,内部查询都要执行一次。

• 例 每个班级高于平均的用户信息, (也可通过分组判断实现)。

SELECT a.id,a.name, a.age ,a.c_class ,a.c_score 
FROM student a
WHERE a.c_score >(SELECT AVG(b.c_score) FROM student b WHERE b.c_class = a.c_class);

EXISTS和NOT EXISTS操作符

• 相关子查询还可使用EXISTS和NOT EXISTS操作符。

• EXISTS判断存在与否。具体操作如下:

– 子查询中如果有记录找到,子查询语句不会继续执行,返回 值为TRUE;
– 子查询中如果到表的末尾也没有记录找到,返回值为FALSE。

• EXISTS子查询并没有确切记录返回,只判断是否有记录。而且 只要找到相关记录,子查询就不需要再执行,然后再进行下面 的操作。这样大大提高了语句的执行效率。

• NOT EXISTS正好相反,判断子查询是否没有返回值。如果没 有返回值,表达式为真,如果找到一条返回值,则为假。

• 例 查询用户表的班级ID 存在于班级表中的数据。

SELECT a.id,a.name, a.age ,a.c_class ,a.c_score 
FROM student a
WHERE EXISTS (SELECT 1 FROM student b WHERE b.c_class = a.c_class);

• 因为EXISTS子句中,并没有确切记录返回,只返回真或假。所 以’1’只是占位用,无实际意义。

• 例 查询用户表的班级ID 不存在于班级表中的数据。

SELECT a.id,a.name, a.age ,a.c_class ,a.c_score 
FROM student a
WHERE NOT EXISTS (SELECT 1 FROM student b WHERE b.c_class = a.c_class);

• NOT EXISTS操作符因为运算方法与NOT IN不同,只会返回 TRUE或FALSE,不会返回空值,所以不需要考虑子查询去除 空值的问题。


/   总结   /

本文主要讲了子查询相关介绍,子查询就像是父与子的嵌套关系,当一种查询情况不满足时,我们可以使用这种嵌套关系去处理。

往期推荐:

如何入门做软件开发

为什么我不推荐入行程序员

做全栈开发很难吗

关注我的公众号,学习技术或投稿

长按上图,识别图中二维码即可关注


文章转载自罗晓胜,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论