Mysql(7)子查询

news2026/4/15 1:52:18
提示文章写完后目录可以自动生成如何生成可参考右边的帮助文档文章目录子查询select中嵌套子查询select中嵌套子查询where或having中嵌套子查询exists型子查询from中嵌套子查询update中嵌套子查询delete中嵌套子查询使用子查询复制表结构和数据通用表达式一、整体总结1. 子查询Subquery2. CTECommon Table Expressions 通用表达式3. 递归 CTERECURSIVE CTE二、各类子查询核心用法总结1. SELECT 中嵌套子查询2. WHERE / HAVING 中嵌套子查询3. FROM 中嵌套子查询派生表4. UPDATE / DELETE 中嵌套子查询三、高频易错点汇总重点子查询select中嵌套子查询子查询嵌套在另一个SQL语句中的查询。select语句可以嵌套在另一个select、update、delete、insert、create等语句中。select中嵌套子查询--在t_employee表中查询每个人薪资和公司平均薪资的差值--并显示员工薪资和公司平均薪资相差5000元以上的记录 select enameas姓名,salaryas薪资,round((select avg(salary)fromt_employee),2)as全公司平均薪资,round(salary-(select avg(salary)fromt_employee),2)as差值fromt_employee whereabs(round(salary-(select avg(salary)fromt_employee),2))5000;--在t_employee表中查询每个部门平均薪资和公司平均薪资的差值 select did,avg(salary),avg(salary)-(select avg(salary)fromt_employee)fromt_employee group by did;where或having中嵌套子查询当子查询结果作为外层另一个SQL的过滤条件通常把子查询嵌入到where或having中。根据子查询结果的情况分为如下三种情况当子查询的结果是单列单个值那么可以直接使用比较运算符如“”、“”、“”、“”、“”、“!”等与子查询结果进行比较当子查询的结果是单列多个值那么可以使用比较运算符in或not in进行比较当子查询的结果是单列多个值还可以使用比较运算符, 如“”、“”、“”、“”、“”、“!”等搭配any、all等关键字与查询结果进行比较子查询结果一列一行--在t_employee表中查询比全公司平均薪资高的男员工姓名和薪资 select ename,salaryfromt_employee where salary(select avg(salary)fromt_employee)andgender男;子查询一列多行--在t_employee表中查询和 白露谢吉娜 同一部门的员工姓名和电话 select ename,tel,didfromt_employee where didin(select didfromt_employee where ename白露orename谢吉娜);--在t_employee表中查询薪资比 白露李诗雨黄冰茹 三个人的薪资都要高的员工姓名和薪资 select ename,salaryfromt_employee where salaryall(select salaryfromt_employee where enamein(白露,李诗雨,黄冰茹))--查询t_employee和t_department表按部门统计平均工资--显示部门平均工资比全公司的总平均工资高的部门编号、部门名称、部门平均薪资--并按照部门平均薪资升序排列 select t_department.did,dname,avg(salary)fromt_employee right join t_department on t_employee.didt_department.did group by t_department.did having avg(salary)(select avg(salary)fromt_employee)order by avg(salary);exists型子查询比如下面第一个案例也就是相当于对t_department的每一行进行判断其的did是否为null,并且exists中的select是什么事无所谓的比如看结果--查询t_employee表中是否存在部门编号为null的员工--如果存在查询t_department表的部门编号、部门名称 select*fromt_department where exists(select*fromt_employee where didisnull);同样的道理也是看t_department的每一行是否满足这个t_employee.didt_department.did条件满足的返回--查询t_department表是否存在与t_employee表相同部门编号的记录--如果存在查询这些部门的编号和名称 select*fromt_department where exists(select*fromt_employee where t_employee.didt_department.did);结果如下筛选去掉了一个测试部因为测试部门的id在员工表中不存在等价于--查询结果等价于下面的SQL select distinct t_department.*fromt_department inner join t_employee on t_department.didt_employee.did;from中嵌套子查询当子查询结果是多列的结果时通常将子查询放到from后面然后采用给子查询结果取别名的方式把子查询结果当成一张“动态生成的临时表”使用。若是使用这种方式select ename,did,salary,dense_rank()over(partition by did order by salary desc)aspaimingfromt_employee where dense_rank()over(partition by did order by salary desc)2;窗口函数是最后一步进行计算的所以报错sql中的执行顺序FROM→ WHERE→ GROUP BY→ HAVING→ SELECT ✅窗口函数在这里算# 在t_employee表中查询每个部门中薪资排名前2的员工姓名、部门编号和薪资select*from(select ename,did,salary,dense_rank()over(partition by did order by salary desc)aspaimingfromt_employee)temp where temp.paiming2;update中嵌套子查询--修改t_employee表中部门编号和测试部部门编号相同的员工薪资为原来薪资的1.5倍 update t_employeesetsalarysalary*1.5where did(select didfromt_department where dname测试部);--修改t_employee表中did为null的员工信息--将他们的did值修改为测试部的部门编号--这种子查询必须是单个值否则无法赋值 update t_employeesetdid(select didfromt_department where dname测试部)where didisnull;– 当update的表和子查询的表是同一个表时需要将子查询的结果用临时表的方式表示– 即再套一层子查询使得update和最外层的子查询不是同一张表update t_employeesetdid(select didfromt_department where dname测试部)where didisnull;所以使用下面的办法嵌套作为一个临时表--修改t_employee表中李冰冰的薪资值等于孙红梅的薪资值 update t_employeesetsalary(select salaryfrom(select salaryfromt_employee where ename孙红梅)temp)where ename李冰冰;– 修改t_employee表李冰冰的薪资与她所在部门的平均薪资一样注意一定要给临时表起别名否则报错update t_employee tsetsalary(select pingfrom(SELECT avg(salary)pingfromt_employee t2 where t.didt2.did)tmp)where ename李冰冰;delete中嵌套子查询--从t_employee表中删除测试部的员工记录 deletefromt_employee where did(select didfromt_department where dname测试部);--从t_employee表中删除和李冰冰同一个部门的员工记录 deletefromt_employee where did(select didfromt_employee where ename李冰冰);--报错因为删除和子查询是同一张表和上面同样的处理方式设置一个临时表delete from t_employeewhere did (select did from(SELECT did from t_employee where ename‘李冰冰’)temp)使用子查询复制表结构和数据1复制表结构– 仅复制表结构可以用create语句create table department like t_department;2复制一条或多条记录– 使用insert语句子查询复制数据此时insert不用写valuesinsert into department (select * from t_department where did3);3同时复制表结构和记录– 同时复制表结构数据create table d_department as (select * from t_department);– 如果select后面是部分字段复制的新表就只有这一部分字段通用表达式通用表达式简称为CTECommon Table Expressions。CTE是命名的临时结果集作用范围是当前语句。CTE可以理解为一个可以复用的子查询但是和子查询又有区别一个CTE可以引用其他CTECTE还可以是自引用(递归CTE)也可以在同一查询中多次引用但子查询不可以。with[recursive]cte_name[(字段名1,字段名2)]as(子查询),cte_name[(字段名1,字段名2)]as(子查询)– 在t_employee表中查询每个人薪资和公司平均薪资的的差值SELECT*FROM(SELECT ename AS员工姓名,salary AS薪资,AVG(salary)OVER()AS pingjun,ROUND(salary-AVG(salary)OVER(),2)AS差值FROM t_employee)t WHERE ROUND(t.薪资-t.pingjun,2)5000;可以这样写– 查询薪资低于9000的员工编号员工姓名员工薪资领导编号领导姓名领导薪资但是也可以使用CTE来替代子查询WITH empas(SELECT*fromt_employee where salary9000)select emp.salaryas员工薪资,emp.enameas员工姓名,emp.midas领导编号,mgr.enameas领导姓名,mgr.salaryas领导薪资fromemp join t_employee mgr on emp.midmgr.eid;--查询eid为21的员工和他所有领导直到最高领导--建表设置多层领导 create table empas(select eid,ename,salary,tel,midfromt_employee where salary10000);update empsetmid19where eid21;update empsetmid17where eid19;update empsetmid16where eid17;update empsetmid15where eid16;update empsetmid4where eid15;update empsetmidnull where eid4;select*fromemp;withrecursive cteas(select eid,ename,midfromemp where eid21unionallselect emp.eid,emp.ename,emp.midfromemp join cte on emp.eidcte.mid where emp.eidisnotnull)select*fromcte;这里CET循环解释一下循环有三个条件起始递归终止首先是起始select eid,ename,midfrom empwhere eid 21循环部分,相当于不断地在结果上进行递加union allselect emp.id emp.ename,emp.midfrom emp join cteon cte.midemp.eid终止条件where emp eid is not null总结一、整体总结1. 子查询Subquery子查询是指嵌套在其他 SQL 语句中的查询可以出现在SELECT、FROM、WHERE、HAVING、UPDATE、DELETE等位置。核心特点子查询先执行其结果作为外层 SQL 的条件或数据源。根据返回结果不同可分为单行单列、单列多行、多列多行。执行顺序子查询总是优先于主查询执行。2. CTECommon Table Expressions 通用表达式CTE 是MySQL 8.0引入的特性可以理解为可以命名的临时结果集只在当前语句有效。与子查询的区别对比项子查询CTE通用表达式是否需要命名不需要from中必须必须命名可重复使用不可以可以多次引用是否可相互引用不可以可以CTE 可以引用其他 CTE是否支持递归不支持支持加RECURSIVE可读性差嵌套多层很乱优秀结构清晰语法结构WITH[RECURSIVE]cte_name1AS(子查询1),cte_name2AS(子查询2)SELECT...FROMcte_name1...3. 递归 CTERECURSIVE CTE递归 CTE 是 CTE 的进阶用法用于处理层级关系、树形结构如查找所有上级、所有下属、组织架构等。核心组成种子查询提供起始点第一层数据递归查询通过UNION ALLJOIN自己调用自己终止条件当递归查询不再返回结果时自动停止执行本质像“滚雪球”一样一行一行不断累积结果而不是“在表格后面添加列”。二、各类子查询核心用法总结1. SELECT 中嵌套子查询常用于返回单值如公司平均薪资每次外层查询一行子查询就会执行一次性能较差2. WHERE / HAVING 中嵌套子查询单行单列直接用、、等比较单列多行用IN、ANY、ALLHAVING中可使用聚合函数WHERE中不能3. FROM 中嵌套子查询派生表子查询结果当作临时表使用必须给别名常用于窗口函数后筛选因为窗口函数在SELECT中最后计算4. UPDATE / DELETE 中嵌套子查询更新同一张表时容易出现You cant specify target table错误解决办法把子查询再包一层成为临时表三、高频易错点汇总重点以下是这篇笔记中最容易出错的地方按严重程度排序序号易错点具体表现正确做法1窗口函数写在 WHERE 中WHERE dense_rank() OVER(...) 2必须包一层子查询在外层用WHERE筛选2UPDATE/DELETE 与子查询操作同一张表报You cant specify target table子查询外面再包一层临时表3HAVING 中使用 SELECT 的别名HAVING 差值 5000外层用子查询或者重复写表达式4递归 CTE 方向写反ON emp.eid cte.mid想找上级却写成向下向上找领导用ON e.eid cte.mid向下找下属用ON e.mid cte.eid5递归 CTE 没有终止条件导致Recursive query aborted after 1001 iterations加上level字段 WHERE cte.level 20限制6子查询返回多行却用WHERE did (SELECT did ...)返回多行时报错改用IN7FROM 子查询不写别名FROM (SELECT ...)没给别名必须写别名如FROM (...) t8EXISTS 子查询写法混淆把EXISTS当成返回具体值使用EXISTS只关心“有没有结果”不关心内容9CTE 中忘记写 RECURSIVE递归查询无法生效递归必须写WITH RECURSIVE10多表查询不加表别名导致 ambiguousColumn eid is ambiguous所有字段都加上表别名如emp.eid、mgr.eid

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

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

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…