【MySQL】子查询

文章目录

  • 子查询
  • 一、子查询的基本使用
    • 子查询的分类
  • 二、单行子查询
    • 2.1 单行比较操作符
    • 2.2 HAVING 中的子查询
    • 2.3 CASE中的子查询
    • 2.4 子查询中的空值问题
    • 2.5 非法使用子查询
  • 三、多行子查询
    • 3.1 多行比较操作符
    • 3.2 ANY与ALL的区别
  • 四、相关子查询
    • 4.1 相关子查询执行流程
      • 4.1.1 代码示例
    • 4.3 在ORDER BY 中使用子查询:
    • 4.4 EXISTS 与 NOT EXISTS关键字
    • 4.5 相关更新
    • 4.6 相关删除
  • 总结


子查询

此前都是根据各种条件查询出一个结果或数据,子查询是对这个结果数据再次的比较,打印结果。
举例:

#查询出 比last_name为'Abel' 薪资salary要高的员工ID与名字# 方式一:查出'Abel'的工资 再查比这个工资高的员工
SELECT salary
FROM employees
WHERE last_name = 'Abel';SELECT last_name,salary
FROM employees
WHERE salary > 11000;# 方式二:自连接
SELECT e2.employee_id,e2.last_name,e2.salary
FROM employees e1,employees e2
WHERE e1.last_name = 'Abel'
AND e1.salary < e2.salary ;# 方式三:子查询
SELECT employee_id,last_name,salary
FROM employees
WHERE salary > 
(SELECT salaryFROM employeesWHERE last_name = 'Abel'
);

1


一、子查询的基本使用

语法格式:
2

  • 子查询(内查询)在主查询之前一次执行完成。
  • 子查询的结果被主查询(外查询)使用 。

注意事项

  • 子查询要包含在括号内
  • 将子查询放在比较条件的右侧
  • 单行操作符对应单行子查询,多行操作符对应多行子查询

子查询的分类

第一种分类方式:
内查询的结果返回一条还是多条记录,将子查询分为单行子查询多行子查询

  • 单行子查询
    3
  • 多行子查询
    4
    第二种分类方式:
    按内查询是否被执行多次,将子查询划分为相关(或关联)子查询不相关(或非关联)子查询

子查询从数据表中查询了数据结果,如果这个数据结果只执行一次,然后这个数据结果作为主查询的条件进行执行,那么这样的子查询叫做不相关子查询

子查询需要执行多次,即采用循环的方式,先从外部查询开始,每次都传入子查询进行查询,然后再将结果反馈给外部,这种嵌套的执行方式就称为相关子查询

二、单行子查询

2.1 单行比较操作符

操作符含义
=equal to
>greater than
>=greater than or equal to
<less than
<=less than or equal to
<>not equal to
# 查询工资大于149号员工工资的员工的信息
SELECT employee_id,last_name,salary 
FROM employees
WHERE salary > (SELECT salary FROM employeesWHERE employee_id = 149
);

jeiguo

# 返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资
SELECT  employee_id,last_name,job_id,salary
FROM employees
WHERE job_id = 
(SELECT job_id FROM employeesWHERE employee_id = 141
)
AND salary > 
(SELECT salaryFROM employeesWHERE employee_id = 143
);

2

# 返回公司工资最少的员工的last_name,job_id和salary
# 方法一:单行子查询
SELECT last_name,job_id,salary
FROM employees
WHERE salary = 
(SELECT MIN(salary)FROM employees
);
# 方法二:order by + limit
SELECT last_name,job_id,salary
FROM employees 
ORDER BY salary ASC
LIMIT 0,1;

1
问题:
查询与141号或174号员工的manager_id和department_id相同的其他员工的employee_id,manager_id,department_id

# 不成对比较方式:
SELECT employee_id,manager_id,department_id
FROM employees
WHERE manager_id IN
(SELECT manager_idFROM employeesWHERE employee_id IN (141,174)
)
AND department_id IN 
(SELECT department_idFROM employeesWHERE employee_id IN (141,174)
)
AND employee_id NOT IN (141,174);
# 成对比较方法
SELECT employee_id,manager_id,department_id
FROM employees
WHERE (manager_id,department_id) IN 
(SELECT manager_id,department_idFROM employeesWHERE employee_id IN (141,174)
)
AND employee_id NOT IN (141,174);

2

2.2 HAVING 中的子查询

  • 首先执行子查询。
  • 向主查询中的HAVING 子句返回结果。
# 查询每个部门的最低工资, 但每个部门最低工资是大于50号部门的最低工资 ,显示部门与它的最低工资
SELECT department_id,MIN(salary)
FROM employees
GROUP BY department_id
HAVING MIN(salary) > 
(SELECT MIN(salary)FROM employeesWHERE department_id = 50
);

1

2.3 CASE中的子查询

# 题目:
# 显示员工的employee_id,last_name和location。
# 其中,若员工department_id与location_id为1800的department_id相同,
# 则location为’Canada’,其余则为’USA’。
SELECT employee_id, last_name,(CASE department_idWHEN(SELECT department_id FROM departmentsWHERE location_id = 1800)           THEN 'Canada' ELSE 'USA' END) location
FROM   employees;

2

2.4 子查询中的空值问题

SELECT last_name, job_id
FROM   employees
WHERE  job_id =(SELECT job_idFROM   employeesWHERE  last_name = 'Haas');

1

子查询不返回任何行

2.5 非法使用子查询

SELECT employee_id, last_name
FROM   employees
WHERE  salary =(SELECT   MIN(salary)FROM     employeesGROUP BY department_id);

2.5

多行子查询使用单行比较符

三、多行子查询

  • 也称为集合比较子查询
  • 内查询返回多行
  • 使用多行比较操作符

3.1 多行比较操作符

3.1

3.2 ANY与ALL的区别

题:返回其它job_id中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary

首先查出 job_id为‘IT_PROG’部门 的全部工资

		SELECT salaryFROM employeesWHERE job_id = 'IT_PROG'

3.2.1

使用ANY:

# 返回其它job_id中比job_id为‘IT_PROG’部门任一工资低的员工的员工号、姓名、job_id 以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary < ANY(SELECT salaryFROM employeesWHERE job_id = 'IT_PROG')AND job_id <> 'IT_PROG'; -- <>不等于运算符 --
--  AND job_id != 'IT_PROG';

3.2
3.3

ANY 是 只要和‘IT_PROG’部门 任意一条薪资 对比 比它小就打印

使用ALL:

# 返回其它job_id中比job_id为‘IT_PROG’部门所有工资都低的员工的员工号、姓名、job_id以及salary
SELECT employee_id,last_name,job_id,salary
FROM employees
WHERE salary < ALL(SELECT salaryFROM employeesWHERE job_id = 'IT_PROG')AND job_id <> 'IT_PROG';
--  AND job_id != 'IT_PROG';

3.4

ALL 是 需要和‘IT_PROG’部门 所有薪资 对比 比它们都小得就打印

题目:查询平均工资最低的部门id

# 方法一:
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) <= ALL
(SELECT AVG(salary)FROM employeesGROUP BY department_id
)
方法二:
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) = 
(SELECT MIN(avg_sal)FROM (SELECT AVG(salary) avg_salFROM employeesGROUP BY department_id) dept_avg_sal
)

四、相关子查询

结论:在SELECT中,除了GROUP BY 和 LIMIT之外,其他位置都可以声明子查询!

4.1 相关子查询执行流程

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

相关子查询按照一行接一行的顺序执行,主查询的每一行都执行一次子查询。

4.1.2
说明:子查询中使用主查询中的列

4.1.1 代码示例

题目:查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id

  1. 方法一 关联子查询
    格式
# 查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id
SELECT last_name,salary,department_id
FROM employees e1
WHERE salary > 
(SELECT AVG(salary)FROM employees e2WHERE e1.department_id = e2.department_id
)
  1. 方法二:FROM中子查询
# 查询员工中工资大于本部门平均工资的员工的last_name,salary和其department_id# 使用 FROM中子查询 方式# 即 自建一张表(表中数据是与主表 进行比较使用的)
# 可以先写from 子查询内表 先单独运行 看看SELECT e1.last_name,e1.salary,e1.department_id
FROM employees e1,(SELECT department_id,AVG(salary) avg_sal FROM employees GROUP BY department_id) e2
WHERE e1.department_id = e2.department_id
AND e1.salary > e2.avg_sal# from 内表 先求出了 每个部门的平均工资-->自建表

4.1

from型的子查询:子查询是作为from的一部分,子查询要用()引起来,并且要给这个子查询取别名,
把它当成一张“临时的虚拟的表”来使用。

4.3 在ORDER BY 中使用子查询:

题目:查询员工的id,salary,按照department_name 排序

SELECT employee_id,salary
FROM employees e 
ORDER BY 
(SELECT department_nameFROM departments d WHERE e.department_id = d.department_id
)

4.4 EXISTS 与 NOT EXISTS关键字

  • 关联子查询通常也会和 EXISTS操作符一起来使用,用来检查在子查询中是否存在满足条件的行。
  • 如果在子查询中不存在满足条件的行:
    • 条件返回 FALSE
    • 继续在子查询中查找
  • 如果在子查询中存在满足条件的行:
    • 不在子查询中继续查找
    • 条件返回 TRUE
  • NOT EXISTS关键字表示如果不存在某种条件,则返回TRUE,否则返回FALSE。
# 查询公司管理者的employee_id,last_name,job_id,department_id信息
# 方式一 自连接
SELECT m.employee_id,m.last_name,m.job_id,m.department_id
FROM employees e,employees m 
WHERE e.employee_id = m.employee_id# 方式二 EXISTS子查询
SELECT employee_id,last_name,job_id,department_id
FROM employees e1
WHERE EXISTS 
(SELECT * FROM employees e2 WHERE e1.employee_id = e2.manager_id
)# 方式三 子查询
# employee_id 必须是 manager_id 并且过滤重复的
SELECT employee_id,last_name,job_id,department_id
FROM employees 
WHERE employee_id IN 
(SELECT DISTINCT manager_idFROM employees
);

NOT EXISTS

#查询departments表中,不存在于employees表中的部门的
# department_id和department_name
SELECT department_id,department_name
FROM departments
WHERE NOT EXISTS 
(SELECT department_idFROM employeesWHERE employees.department_id = departments.department_id
)

4.5 相关更新

使用相关子查询依据一个表中的数据更新另一个表的数据。
格式:

UPDATE table1 alias1
SET    column = (SELECT expressionFROM   table2 alias2WHERE  alias1.column = alias2.column);

4.6 相关删除

使用相关子查询依据一个表中的数据删除另一个表的数据。


总结

题目: 员工表中谁的工资比Abel的高?

#方式1:自连接
SELECT e2.last_name,e2.salary
FROM employees e1,employees e2
WHERE e1.last_name = 'Abel'
AND e1.`salary` < e2.`salary`
#方式2:子查询
SELECT last_name,salary
FROM employees
WHERE salary > (SELECT salaryFROM employeesWHERE last_name = 'Abel');

问题:以上两种方式有好坏之分吗?

解答:自连接方式好!

题目中可以使用子查询,也可以使用自连接。
一般情况建议使用自连接,因为在许多 DBMS 的处理过程中,对于自连接的处理速度要比子查询快得多。

可以这样理解:
子查询实际上是通过未知表进行查询后的条件判断,而自连接是通过已知的自身数据表进行条件判断,因此在大部分 DBMS 中都对自连接处理进行了优化。

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

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

相关文章

【大数据进阶第三阶段之Datax学习笔记】使用阿里云开源离线同步工具DataX 实现数据同步

【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax概述 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax快速入门 【大数据进阶第三阶段之Datax学习笔记】阿里云开源离线同步工具Datax类图 【大数据进阶第三阶段之Datax学习笔记】使用…

Django数据库选移的preserve_default=False是什么意思?

有下面的迁移命令&#xff1a; migrations.AddField(model_namemovie,namemov_group,fieldmodels.CharField(defaultdjango.utils.timezone.now, max_length30),preserve_defaultFalse,),迁移命令中的preserve_defaultFalse是什么意思呢&#xff1f; 答&#xff1a;如果模型定…

数学建模.皮尔逊相关系数假设检验

一、步骤 查表找临界值 二、更好的方法 三、使用条件 作图可以使用spss 这个图对不对还不好说&#xff0c;因为还没进行正态分布的验证 四、正态分布验证 &#xff08;1&#xff09;JB检验 所以之前的数据的那个表是错的&#xff0c;因为不满足正态分布 &#xff08;2&#xff…

基于Token认证的登录功能实现

Session 认证和 Token 认证过滤器和拦截器 上篇文章我们讲到了过滤器和拦截器理论知识以及 SpringBoot 集成过滤器和拦截器&#xff0c;本篇文章我们使用过滤器和拦截器去实现基于 Token 认证的登录功能。 一、登录校验 Filter 实现 1.1、Filter 校验流程图 获得请求 url。判…

C语言入门教程,C语言学习教程(第三部分:C语言变量和数据类型)一

第三部分&#xff1a;C语言变量和数据类型 本章也是C语言的基础知识&#xff0c;主要讲解变量、数据类型以及运算符&#xff0c;这其中涉及到了数据的存储格式以及不同进制。 一、大话C语言变量和数据类型 在《数据在内存中的存储&#xff08;二进制形式存储&#xff09;》一…

性能分析与调优: Linux 内存观测工具

目录 一、实验 1.环境 2.vmstat 3.PSI 4.swapon 5.sar 6.slabtop 7.numstat 8.ps 9.top 10.pmap 11.perf 12.bpftrace 二、问题 1.接口读写报错 2.slabtop如何安装 3.numactl如何安装 4.numad启动服务与关闭NUMA 5. perf如何安装 6. kernel-lt-doc与kern…

MySQL:索引失效场景总结

1 执行计划查索引 通过执行计划命令可以查看查询语句使用了什么索引。 EXPLAIN SELECT * FROM ods_finebi_area WHERE areaName = 福建 执行查询计划后,key列的值就是被使用的索引的名称,若key列没有值表示查询未使用索引。 2 在什么列上创建索引 (1)列经常被用于where…

Multi-View-Information-Bottleneck

encoder p θ ( z 1 ∣ v 1 ) _θ(z_1|v_1) θ​(z1​∣v1​)&#xff0c;D S K L _{SKL} SKL​ represents the symmetrized KL divergence. I ˆ ξ ( z 1 ; z 2 ) \^I_ξ(z_1; z_2) Iˆξ​(z1​;z2​) refers to the sample-based parametric mutual information estimatio…

【PyTorch简介】3.Loading and normalizing datasets 加载和规范化数据集

Loading and normalizing datasets 加载和规范化数据集 文章目录 Loading and normalizing datasets 加载和规范化数据集Datasets & DataLoaders 数据集和数据加载器Loading a Dataset 加载数据集Iterating and Visualizing the Dataset 迭代和可视化数据集Creating a Cust…

memory泄露分析方法(java篇)

#memory泄露主要分为java和native 2种&#xff0c;本文主要介绍java# 测试每天从monkey中筛选出内存超标的app&#xff0c;提单流转到我 首先&#xff0c;辨别内存泄露类型&#xff08;java&#xff0c;还是native&#xff09; 从采到的dumpsys_meminfo_pid看java heap&…

网络技术基础入门全套实验-厦门微思网络CCNA实验手册

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 微思简介&#xff08;https://www.xmws.cn) 微思成立于2002年&#xff0c;是一个诚信敬业、积极向上、充满活力、专注技术服务的企业。 微思获得了八…

LeetCode讲解篇之2280. 表示一个折线图的最少线段数

文章目录 题目描述题解思路题解代码 题目描述 题解思路 折线图中如果连续的线段共线&#xff0c;那么我们可以可以将其合并成一条线段 首先将坐标点按照横坐标升序排序 然后遍历数组 我们可以通过计算前一个线段的斜率和当前线段的斜率来判断是否共线 如果二者相等&#x…

Open3D 两片点云的最小/最大距离(23)

Open3D 两片点云的最小/最大距离(23) 一、效果展示二、使用步骤1.代码三、cloudcompare量距小工具一、效果展示 算法与实际量测的结果保持一致,输出最近距离和对应点 二、使用步骤 1.代码 import open3d as o3d import numpy as np# 读取点云数据 cloud_2 = o3d.io.re…

硬盘无法写入文件的解决方法 在Mac中的特殊符号如何打 tuxera ntfs for Mac 磁盘读写工具

今天将为大家介绍一下怎么在Mac中输入特殊符号&#xff0c;希望能够给大家带来帮助。 图&#xff1a;Mac中的特殊符号 苹果符号 按下ShiftOptionK就可以插入Apple logo了&#xff0c;不过要注意的是&#xff0c;在Windows可能直接显示为一个框框&#xff0c;而Linux系统则有可…

uni微信小程序强制用户更新版本

强制更新的代码参考官方文档 uni.getUpdateManager() | uni-app官网 我这边的如下&#xff1a; //检查版本更新const updateManager uni.getUpdateManager();updateManager.onCheckForUpdate(function (res) {// 请求完新版本信息的回调console.log(res.hasUpdate, "是…

基于java的SSM框架实现在线投稿网站系统项目【项目源码+论文说明】计算机毕业设计

基于java的SSM框架Vue实现在线投稿网站系统演示 摘要 随着计算机技术的飞速发展&#xff0c;稿件也已进入信息化时代。为了使稿件管理更高效、更科学&#xff0c;决定开发投稿审稿系统。 本文采用自顶向下的结构化的系统分析方法&#xff0c;阐述了一个功能全面的投稿审稿系统…

uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -全局异常统一处理实现

锋哥原创的uniapp微信小程序投票系统实战&#xff1a; uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…

GPT实战系列-简单聊聊LangChain搭建本地知识库准备

GPT实战系列-简单聊聊LangChain搭建本地知识库准备 LangChain 是一个开发由语言模型驱动的应用程序的框架&#xff0c;除了和应用程序通过 API 调用&#xff0c; 还会&#xff1a; 数据感知 : 将语言模型连接到其他数据源 具有代理性质 : 允许语言模型与其环境交互 LLM大模型…

Linux-命名管道

文章目录 前言一、命名管道接口函数介绍二、使用步骤 前言 上章内容&#xff0c;我们介绍与使用了管道。上章内容所讲的&#xff0c;是通过pipe接口函数让操作系统给我们申请匿名管道进行进程间通信。 并且这种进程间通信一般只适用于父子进程之间&#xff0c;那么对于两个没有…

创建一个郭德纲相声GPTs

前言 在这篇文章中&#xff0c;我将分享如何利用ChatGPT 4.0辅助论文写作的技巧&#xff0c;并根据网上的资料和最新的研究补充更多好用的咒语技巧。 GPT4的官方售价是每月20美元&#xff0c;很多人并不是天天用GPT&#xff0c;只是偶尔用一下。 如果调用官方的GPT4接口&…