当前位置: 首页 > news >正文

MySQL 多表查询中,联合查询(UNION) 和子查询

一、联合查询(UNION):合并多个查询结果

联合查询用于将多个独立查询的结果集合并为一个结果集,适用于 “需要从不同表或同一表的不同条件下获取结构一致的数据” 的场景(如合并 “研发部员工” 和 “薪资 > 10000 的员工”)。

1. 核心语法与规则

sql

-- 语法
查询语句1
UNION [ALL]
查询语句2
[UNION [ALL] 查询语句3 ...]
  • 关键规则:① 多个查询的列数必须一致(否则报错);② 列的数据类型需兼容(如intdecimal可兼容,intvarchar通常不兼容);③ UNION会自动去重(删除完全相同的记录);UNION ALL不进行去重,直接合并(性能更好,推荐在确认无重复时使用)。
2. 代码示例

基于emp表数据(部分员工信息如下):

idnameagedept_idsalary
1金庸66520000
2张无忌20112500
3杨晓3318400
4韦一笑66111000
5常遇春43110500
6小昭1916000

需求 1:查询 “研发部(dept_id=1)的员工” 和 “薪资 > 10000 的员工”,合并结果(去重)。

sql

-- 子查询1:研发部员工(dept_id=1)
select name, age, dept_id, salary from emp where dept_id = 1
union  -- 去重合并
-- 子查询2:薪资>10000的员工
select name, age, dept_id, salary from emp where salary > 10000;
  • 结果分析:研发部员工包括张无忌、杨晓、韦一笑、常遇春、小昭;薪资 > 10000 的员工包括金庸(20000)、张无忌(12500)、韦一笑(11000)、常遇春(10500)。合并后去重,最终结果包含:张无忌、杨晓、韦一笑、常遇春、小昭、金庸(共 6 条,无重复)。

需求 2:同上,但保留重复记录(使用UNION ALL)。

sql

select name, age, dept_id, salary from emp where dept_id = 1
union all  -- 不查重,直接合并
select name, age, dept_id, salary from emp where salary > 10000;
  • 结果分析:张无忌、韦一笑、常遇春同时满足两个条件,会被重复显示,最终结果共5(研发部)+4(高薪)=9条。

二、子查询:嵌套在其他查询中的查询

子查询(Subquery)是嵌套在SELECTINSERTUPDATEDELETE等语句中的查询。其中,外层的查询称为 “主查询”,内层的查询称为 “子查询”。

子查询的作用是:先通过子查询获取一个中间结果,再用主查询基于这个结果做进一步处理。根据子查询返回结果的形状,可分为以下 4 类:

1. 标量子查询:返回 “一行一列”(单一值)

标量子查询是最常用的子查询类型,返回结果为单个值(如一个数字、一个字符串),通常用于WHERE子句中,作为条件的一部分(配合=><等比较运算符)。

特点

  • 结果必须是 “一行一列”(若返回多行 / 多列会报错);
  • 可理解为 “用子查询的结果作为一个变量” 参与主查询的条件判断。

代码示例需求:查询与 “张无忌” 同部门的员工(张无忌的dept_id=1)。

步骤:① 先通过子查询获取张无忌的部门 id(dept_id=1);② 主查询基于该部门 id,查询所有同部门员工。

sql

-- 标量子查询:子查询返回张无忌的dept_id(单一值1)
select * from emp 
where dept_id = (select dept_id from emp where name = '张无忌');
  • 结果:返回dept_id=1的所有员工(张无忌、杨晓、韦一笑、常遇春、小昭)。

注意:若子查询可能返回NULL,需避免直接用=(可能无结果),可改用IS NULL;若子查询可能返回多行,需用IN(而非=,否则报错)。

2. 列子查询:返回 “一列多行”

列子查询返回结果为一列数据(多行),通常用于WHERE子句中,配合INNOT INANYALL等关键字使用。

常用关键字

  • IN:主查询结果在子查询返回的列中(如x IN (1,2,3));
  • NOT IN:主查询结果不在子查询返回的列中;
  • ANY:主查询结果满足子查询返回列中的任意一个(如x > ANY(1,3,5) → x>1即可);
  • ALL:主查询结果满足子查询返回列中的所有值(如x > ALL(1,3,5) → x>5才满足)。

代码示例需求 1:查询 “研发部(dept_id=1)” 或 “市场部(dept_id=2)” 的员工(用IN)。

sql

-- 列子查询:返回部门id为1和2(一列两行)
select * from emp 
where dept_id in (select id from dept where name in ('研发部', '市场部'));
  • 子查询解析:select id from dept where name in ('研发部', '市场部')返回12(一列两行);
  • 主查询:筛选dept_id为 1 或 2 的员工(即研发部所有员工,市场部若有员工也会被包含)。

需求 2:查询年龄比研发部(dept_id=1)所有员工都大的员工(用ALL)。

sql

-- 列子查询:返回研发部所有员工的年龄(一列多行:20,33,66,43,19)
select * from emp 
where age > all (select age from emp where dept_id = 1);
  • 子查询结果:研发部员工年龄为20,33,66,43,19
  • 主查询条件age > all(...) → 年龄需大于最大的 66 → 最终只有金庸(66?不,66 不大于 66,所以无结果,可调整为age >= all(...)返回金庸)。
3. 行子查询:返回 “一行多列”

行子查询返回结果为一行数据(多列),通常用于WHERE子句中,配合=IN等运算符,匹配主查询中 “多列组合” 的条件。

特点

  • 结果是 “一行多列”(如(dept_id, managerid) = (1, 2));
  • 适用于 “需要同时匹配多个字段” 的场景(如 “同部门且同领导”)。

代码示例需求:查询与 “杨晓” 同部门且同领导的员工(杨晓的dept_id=1managerid=2)。

sql

-- 行子查询:返回杨晓的dept_id和managerid(一行两列:(1,2))
select * from emp 
where (dept_id, managerid) = (select dept_id, managerid from emp where name = '杨晓');
  • 子查询结果:(1,2)(杨晓的部门 id=1,领导 id=2);
  • 主查询条件:(dept_id, managerid) = (1,2) → 匹配的员工包括杨晓、韦一笑(id=4,dept_id=1managerid=2)、小昭(id=6,dept_id=1managerid=2)。
4. 表子查询:返回 “多行多列”

表子查询返回结果为多行多列(相当于一个临时表),通常用于FROM子句中,作为主查询的 “数据源”(需给子查询起别名)。

特点

  • 结果是一个 “临时表”(多行多列),可像普通表一样参与连接、筛选等操作;
  • 适用于 “需要先对数据做聚合 / 过滤,再与其他表关联” 的场景。

代码示例需求:查询每个部门的平均薪资,以及部门名称(需关联dept表)。

步骤:① 先通过表子查询计算每个部门的平均薪资(dept_idavg_salary,多行多列);② 主查询将子查询结果与dept表连接,获取部门名称。

sql

-- 表子查询:计算每个部门的平均薪资(临时表t)
select d.name as 部门名称, t.avg_salary as 平均薪资 
from (select dept_id, avg(salary) as avg_salary from emp group by dept_id) as t  -- 表子查询必须起别名
join dept d on t.dept_id = d.id;  -- 与部门表连接
  • 子查询解析:select dept_id, avg(salary) ... group by dept_id返回每个部门的平均薪资(如dept_id=1的平均薪资为(12500+8400+11000+10500+6000)/5=9680);
  • 主查询:将临时表tdept表连接,通过dept_id关联,最终显示 “部门名称 + 平均薪资”。

三、子查询与联合查询的对比

类型核心作用适用场景关键特点
联合查询合并多个查询的结果集结果结构一致的多条件数据合并列数需一致,UNION去重,UNION ALL高效
标量子查询返回单一值,作为条件变量基于单个值的筛选(如 “同部门”)一行一列,配合=>
列子查询返回一列多行,用于集合匹配基于多个值的筛选(如 “在某些部门中”)一列多行,配合INANYALL
行子查询返回一行多列,用于多字段匹配同时匹配多个字段(如 “同部门且同领导”)一行多列,配合(a,b) = (子查询)
表子查询返回多行多列,作为临时数据源先聚合 / 过滤,再关联其他表多行多列,需起别名,用于FROM子句

四、总结

  • 联合查询是 “横向合并” 结果集,核心是保证多查询的列结构一致;
  • 子查询是 “嵌套查询”,通过内层查询的结果辅助外层查询,根据返回结果的形状分为标量、列、行、表四种,分别对应不同的使用场景和运算符。

掌握这些技术后,可灵活处理复杂的多表查询需求(如 “查询每个部门薪资最高的员工,且该员工年龄大于部门平均年龄” 等)。

http://www.dtcms.com/a/467394.html

相关文章:

  • 找人做的网站怎么看ftp网站建设移动网络
  • 建网站pc版 (报价)淮安网站建设
  • 【实战记录】MySQL密码遗忘终极解决方案:详解--skip-grant-tables原理与全平台重置流程
  • Linux命令之pgrep用法
  • 网站设计要注意事项网站开发工程师的经验
  • 网站备案 座机wordpress 搭建论坛
  • 保定做网站建设河南网站怎么备案
  • 做网站和维护要多少钱wordpress朋友圈图片不显示
  • 零基础新手小白快速了解掌握服务集群与自动化运维(十一)MySQL数据库基础
  • 超越提示词:Anthropic 揭示下一代AI智能体的关键——上下文工程
  • 永康建设局网站天台县低价网站建设
  • 大数据存储优化:从 Mysql 到 Redis Bitmap ,高效存储用户签到记录
  • 网站地图怎么做的晋江做网站模板
  • 卷积神经网络CNN(一):卷积操作
  • RynnVLA-001-7B: 使用人类演示增强机器人Manipulation--达摩院--2025.9.18--开源
  • 网站怎么更新数据云南模板网站建设公司
  • 三维网格(mesh)
  • 做网站需要哪些人才建设网站的心得
  • 银川网站建设是什么19楼网站模板
  • 建设旅游网站的目标大型网站建设基本流程
  • 卷积神经网络CNN(二):对于图像处理的意义
  • 钢材料 网站建设 中企动力网站备案单位查询
  • 高明专业网站建设哪家好永久免费无代码开发平台网站
  • 基于MATLAB/Simulink的飞行器六自由度控制仿真
  • OpenAI 发布Sora2,还发布了 1 个社交应用(附邀请)
  • 百度网站收录入口橙色的网站
  • 【LeetCode热题100(39/100)】对称二叉树
  • 卖产品怎么做网站湖北省市政工程建设官方网站
  • SHAP可视化代码详细讲解
  • 网站建设小wordpress2019谷歌字体