MySQL 基础 ———— 子查询

引言

承接《MySQL 基础 ———— 连接查询》,本文介绍和展示SQL中子查询的使用。

子查询是出现在其他语句中的select 语句,也称为内查询。外部的查询语句,称为主查询或外查询。

一、子查询的分类和支持的子句

按照子查询出现的位置,可以分为:

select 后面、from 后面、where 或 having 后面、exists 后面(相关子查询)。

按照子查询的结果集或者功能,可以分为:

1、标量子查询(单行子查询,结果集只有一行一列)

2、列子查询(多行子查询,结果集是一列多行)

3、行子查询(多列子查询,结果集是一行多列)

4、表子查询(结果集可能是多行多列)

各子句能够支持的子查询类型: 

SELECT 后面只支持标量子查询。

FROM 后面支持表子查询。

WHERE HAVING 后面支持(重点):标量子查询列子查询、行子查询(较少)。

EXISTS 后面支持表子查询。

二、子查询的特点

1、子查询都要放在小括号里

2、子查询一般放在条件的右侧

3、标量子查询一般配合单行操作符使用:>  <  >=  <=  <>  等,列子查询一般配合多行操作符使用:IN ANY/SOME ALL 等。

三、标量子查询(单行子查询)

标量子查询的结果集是单行单列,即一个确定的值。

员工表:

案例一:查询工资大于王强工资的员工信息。思路:第一步,先查询王强的工资,第二步,通过 where子句,进行筛选。

SELECT * FROM emp WHERE salary >= (SELECT salary FROM emp WHERE emp_name = '王强'
);

案例二:查询部门与张建国的部门相同,工资大于孙岩工资的员工信息。

SELECT * FROM emp
WHERE dept_id = (SELECT dept_id FROM emp WHERE emp_name = '张建国'
)
AND salary > (SELECT salary FROM emp WHERE emp_name = '孙岩'
);

案例三:查询部门最低工资大于 1 号部门最低工资的部门id 和 最低工资。

思路:第一步,先查询 1 号部门的最低工资,第二步,根据上一步的结果集进行条件筛选。

SELECT dept_id, MIN(salary) 部门最低工资
FROM emp
GROUP BY dept_id
HAVING MIN(salary) > (SELECT MIN(salary)FROM empWHERE dept_id = 1
);

四、列子查询(多行子查询)

列子查询返回一列多行,结果集可以看做是某个字段的值的集合,比如 dept_id = {1, 2, 5}。可以配合 IN 、NOT IN 等多行比较操作符一起使用。

常见的多行比较操作符有:

操作符含义
IN / NOT IN等于或不等于结果集中的任意一个
ANY / SOME和子查询返回的某一个值比较
ALL和子查询返回的所有值比较

其中,IN 和 NOT IN 使用频率非常高,ANY 和 SOME 含义相同,但是可读性较差,含义容易混淆,而且可以使用其他方式代替,因此不常使用。例如:a > ANY(10, 20, 30) ,可以替换为:a > MIN(10, 20, 30)

员工表:

案例一:查询孙姓员工所在部门的全部员工信息。

SELECT * FROM emp
WHERE dept_id IN(SELECT dept_id FROM emp WHERE emp_name LIKE '孙%'
);

五、行子查询(一行多列)

行子查询一定会查询出多个列值,这就要求语法有一定的变化,有点类似多个筛选条件,比如:

案例一:查询员工编号最小,且工资最高的员工:

SELECT * FROM emp
WHERE (emp_id, salary) = (SELECT MIN(emp_id), MAX(salary) FROM emp
)

案例二:查询部门id > 2, 且工资 > 8000 的员工信息:

SELECT * FROM emp
WHERE (dept_id, salary) = (SELECT dept_id, salary FROM empWHERE dept_id > 2AND salary > 8000
)

行子查询要求子查询结果集必须只有一条记录,而且查询结果的各个值必须与参数括号里面的各个值对应。由于行子查询本身可以通过其他语句替代,加之在一条记录之上再做查询没什么实际意义,所以应用场景非常有限。

六、表子查询(多行多列)

表子查询一般放在 from 子句后面,充当一个小型的结果集,可以进行常规的筛选,甚至是连接查询。但要求必须要给子查询起别名

案例:查询部门编号大于2, 且工资大于5000 的员工姓名、工资、部门编号、部门名称。

SELECT e.emp_name, e.salary, e.dept_id, d.`dept_name`
FROM (SELECT `emp_name`, dept_id, salary FROM empWHERE dept_id >= 2AND salary > 5000
) e
LEFT JOIN dept d
ON e.dept_id = d.`id`;

整体查询结果:

表子查询也是比较常用的子查询类型。

EXISTS 后面的表子查询

exists()函数值关心参数中是否有值,如果有则输出1, 如果没有就是0.

SELECT EXISTS(SELECT * FROM emp)

另外,EXISTS 函数还可以用于 WHERE 子句后面,含义是“当存在/不存在时执行查询”,效果类似于 COUNT > 0 或 COUNT = 0

SELECT *
FROM dept
WHERE EXISTS(SELECT * FROM emp)

 

SELECT *
FROM dept
WHERE NOT EXISTS(SELECT * FROM emp)

 

七、子查询经典案例

员工表:

部门表:

案例一:查询工资最低的员工信息

SELECT * FROM emp
WHERE salary = (SELECT MIN(salary) FROM emp
)

案例二:查询部门平均工资最低的部门信息:

SELECT * 
FROMdept d,(SELECT MIN(avg_sal),dept_id FROM(SELECT AVG(salary) avg_sal,dept_id FROMemp GROUP BY dept_id) sal) lowest 
WHERE d.`id` = lowest.dept_id ;

其实这种子查询是完全可以简化的,比如通过排序或 LIMIT 子句等。

总结

SELECT 后面只支持标量子查询。

FROM 后面支持表子查询。

WHERE HAVING 后面支持(重点):标量子查询列子查询、行子查询(较少)。

EXISTS 后面支持表子查询。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/558730.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL 基础 ———— SQL语句的执行顺序与 LIMIT 子句

引言 到目前为止&#xff0c;已经总结了常见的SQL子句&#xff0c;包括 SELECT 、FROM、JOIN ... ON、WHERE、GROUP BY、HAVING、ORDER BY。 虽然SQL的书写顺序是固定的&#xff0c;但在MySQL引擎中执行的顺序并不完全和书写顺序一致。除了上述这些子句&#xff0c;下面将会介…

MySQL 基础———— UNION 联合查询

引言 联合查询与连接查询不同&#xff0c;通过UNION 关键字&#xff0c;我们可以将多个查询语句一同执行并将结果集展示出来&#xff0c;不涉及到任何关联关系。 UNION 的含义是“联合&#xff0c;并集&#xff0c;结合”&#xff0c;在MySQL中可以将多个查询语句的结果合并成…

MySQL 基础————常用数据类型

引言 从第一次学习mysql开始&#xff0c;不知道为什么MySQL的数据类型始终没有像Java 一样深入脑海&#xff0c;对某些数据类型的定义和用法&#xff0c;也并不清晰&#xff0c;这篇文章&#xff0c;就好好总结一番&#xff0c;将MySQL中几个常用的数据类型归纳一下。 一、类…

MySQL 基础 ———— SAVEPOINT 的应用

引言 savepoint 关键字用于在数据库事务中设置一个存储点&#xff0c;在一个较长的事务中暂存数据&#xff0c;如果在事务末尾执行回滚&#xff0c;可选择性的回滚到 savepoint 设置的暂存点。 本文承接上一篇博客《MySQL 基础 ————事务与隔离级别总结》&#xff0c;进一…

MySQL 基础 ———— 视图的应用与总结

引言 视图是一种虚拟表&#xff0c;和普通表的使用是一样的&#xff0c;视图的一大特点就是“临时性”&#xff0c;是通过表动态生成的数据&#xff0c;只保存SQL逻辑&#xff0c;不保存查询结果。 视图在实际生产中主要有两种应用场景&#xff1a; 1、多个地方用到同样的查…

MySQL 基础 ———— 变量

一、MySQL系统变量 系统变量是由系统提供&#xff0c;属于服务器层面。 系统变量分为&#xff1a;全局变量和会话变量。 全局变量一般要加 GLOBAL 关键字&#xff0c;例如在《MySQL 基础 ————事务与隔离级别总结》中提到的 GLOBAL TRANSACTION&#xff0c;就属于全局变量…

MySQL 基础 ———— 存储过程与函数

一、存储过程介绍 存储过程是一组预先编译好的SQL语句的集合&#xff0c;可理解成批处理语句。它的优点主要有以下几点&#xff1a; 1、提高代码的重用性&#xff1b; 2、简化操作&#xff1b; 3、减少了编译次数并且减少了和数据库服务器的连接次数&#xff0c;提高了效率…

MySQL 基础 ———— 流程控制结构

引言 MySQL 中的流程控制作为基础知识的最后一块拼图&#xff0c;显得并不是特别重要&#xff0c;而且&#xff0c;在实际生产开发中&#xff0c;也往往不需要通过它来进行程序的控制&#xff0c;那么为什么还要学习它呢&#xff1f;我认为有以下几点&#xff1a; 1、知识的完…

MySQL 高级 ———— MySQL逻辑架构图简介

引言 本篇文章介绍MySQL的逻辑架构图。 MySQL并不完美&#xff0c;但足够灵活&#xff0c;能够适应高要求环境。MySQL不仅可以嵌入到应用程序中&#xff0c;同时也可以支持数据仓库、内容搜索、和部署软件、高可用的冗余系统、在线事务处理系统等各种应用类型。 一、MySQL逻…

Java正则表达式总结

引言 正则表达式&#xff08;英文&#xff1a;regular expression&#xff09;是用于描述字符串规则的工具&#xff0c;是记录文本规则的代码。 它可以用来搜索、编辑、处理文本。现有编程语言都支持正则表达式的处理&#xff0c;但每种语言都有细微的差别。 在Java 中&…

Linux 实操 —— 日志筛选操作(sed与wc命令介绍)

引言 在处理数据交互业务场景的问题时&#xff0c;经常会出现需要统计日志中出现某些指定关键字的行数&#xff0c;或者行数&#xff0c;那么如何通过Linux 命令来快速统计一段时间之内&#xff0c;某个特定关键字出现的行数呢&#xff1f;这篇文章将会给你答案。 一、快速统…

Java 注解知识总结

引言 本博客总结自《Java 编程思想》第 20 章。 一、什么是注解 注解是 Java 5 引入的一种通过反射机制实现的语法特性&#xff0c;开发者可以通过在类、域、方法等元素前面标记一个“标签”达到对程序的源码、类信息或运行时进行某种说明或处理的效果&#xff0c;尽可能地简…

Linux 实操 —— Linux 系统性能分析

引言 最近配合解决压测&#xff08;性能测试&#xff09;方面的问题&#xff0c;了解到了一些可以监控 Linux 系统性能指标&#xff0c;如CPU、IO、内存等的工具。 此篇博客主要讲解 Linux 系统监控的一些重点内容以及 sar 命令的使用。 一、Linux 性能分析聚焦 Linux 性能…

Java 动态代理解析

引言 本博客总结自《Java 编程思想》第十四章 一、实现第一个动态代理程序 代理是软件设计中重要的设计思想&#xff0c;它允许我们在调用实际操作之前或之后解耦式地编写额外的操作&#xff0c;而一旦不需要这些操作了&#xff0c;就可以轻易的移除它们。 浏览了《编程思想…

MySQL 基础 ————高频函数总结

一、MySQL函数调用方式 函数调用的基本语法&#xff1a; SELECT 函数(实参列表) [FROM 表] 其中&#xff0c;对于函数&#xff0c;需要重点关注三点&#xff1a; 1、函数的名称 2、参数列表 3、函数功能 二、函数的分类 在 MySQL中&#xff0c;函数分为两类&#xff1a;1、…

MySQL 高级 —— 复合索引简介(多列索引)

引言 复合索引是指包含多个数据列的索引&#xff0c;与之概念相对的是单列索引&#xff0c;仅包含一个数据列。在大多数情况下&#xff0c;建立多列索引的好处都要多于单列索引。另外&#xff0c;复合索引最多支持16个列&#xff0c;但请一定不要让复合索引包含太多的列&#…

MySQL 优化 —— SQL优化概述(优化专题开篇词)

引言 最近为了研究索引的知识&#xff0c;特地去MySQL 官网研读了一番&#xff0c;发现MySQL官网有比较全面的MySQL优化方案和知识背景&#xff0c;所以希望通过一系列文章&#xff0c;将官网的知识翻译总结一下&#xff0c;避免日后去网上胡乱搜索产生不必要的知识勘误风险。…

MySQL 优化 —— WHERE 子句优化

引言 本文翻译自 MySQL 官网&#xff1a;WHERE Clause Optimization WHERE 子句优化 这一部分我们来讨论对 WHERE 子句的优化处理。本部分的案例都是以 SELECT 语句为例&#xff0c;但这些优化同样适用于 DELETE 和 UPDATE 语句中的 WHERE 子句。 注意 因为对 MySQL 优化器的…

MySQL 优化 —— IS NULL 优化

引言 本博客翻译自 MySQL 官网&#xff1a;IS NULL Optimization&#xff0c; MySQL版本 5.7。 MySQL 对 IS NULL 的优化 MySQL 可以对 IS NULL 执行和常量等值判断&#xff08;列名 常量表达式&#xff0c;如name Tom&#xff09;相同的优化。MySQL 可以利用索引和范围来…

MySQL 优化 —— ORDER BY 优化

引言 本文翻译自MySQL 官网&#xff1a;ORDER BY Optimization&#xff0c;MySQL 版本&#xff1a;5.7。 这一部分描述了MySQL何时会使用索引来满足order by子句&#xff0c;filesort 操作会在索引不能生效的时候被用到&#xff0c;以及优化器对order by的执行计划信息。 or…