当前位置: 代码网 > it编程>数据库>Mysql > MySQL中的复合查询使用解读

MySQL中的复合查询使用解读

2025年12月26日 Mysql 我要评论
在实际开发中,仅用单表查询显然无法满足复杂业务需求。今天我们就以经典的员工管理系统(emp员工表、dept部门表、salgrade工资级别表)为例,聊聊 mysql 复合查询的核心玩法 —

在实际开发中,仅用单表查询显然无法满足复杂业务需求。今天我们就以经典的员工管理系统(emp员工表、dept部门表、salgrade工资级别表)为例,聊聊 mysql 复合查询的核心玩法 —— 从单表查询到多表联查、子查询,再到合并查询,每一步都附上真实查询结果,帮你直观理解。

一、先回顾:单表查询的基础操作(以emp表为例)

先明确emp表基础数据(对应图片中表内容):

empnoenamejobmgrhiredatesalcommdeptno
7369smithclerk79021980-12-17800null20
7499allensalesman76981981-02-20160030030
7521wardsalesman76981981-02-22125050030
7566jonesmanager78391981-04-022975null20
7654martinsalesman76981981-09-281250140030
7698blakemanager78391981-05-012850null30
7782clarkmanager78391981-06-092450null10
7788scottanalyst75661987-04-193000null20
7839kingpresidentnull1981-11-175000null10
7844turnersalesman76981981-09-081500030
7876adamsclerk77881987-05-231100null20
7900jamesclerk76981981-12-03950null30
7902fordanalyst75661981-12-033000null20
7934millerclerk77821982-01-231300null10

1. 带条件的筛选

select * from emp 
where (sal>500 or job='manager') 
and ename like 'j%';

查询结果

empnoenamejobmgrhiredatesalcommdeptno
7566jonesmanager78391981-04-022975null20
7900jamesclerk76981981-12-03950null30

2. 排序与计算字段

(1)按部门号升序、工资降序排列

select * from emp 
order by deptno, sal desc;

查询结果(节选核心字段):

empnoenamesaldeptno
7839king500010
7782clark245010
7934miller130010
7788scott300020
7902ford300020
7566jones297520
7876adams110020
7369smith80020
7698blake285030
7499allen160030
7844turner150030
7521ward125030
7654martin125030
7900james95030

(2)计算年薪(工资 ×12 + 奖金,奖金为空则按 0 算)并排序

select ename, sal*12+ifnull(comm,0) as '年薪' 
from emp 
order by 年薪 desc;

查询结果

ename年薪
king60000
scott36000
ford36000
jones35700
blake34200
clark29400
allen19500
turner18000
martin16400
miller15600
ward15500
adams13200
james11400
smith9600

3. 聚合与分组查询

(1)查每个部门的平均工资、最高工资

select deptno, format(avg(sal),2) as avg_sal, max(sal) as max_sal 
from emp 
group by deptno;

查询结果

deptnoavg_salmax_sal
102,916.675000
202,175.003000
301,566.672850

(2)筛选平均工资 < 2000的部门

select deptno, avg(sal) as avg_sal 
from emp 
group by deptno 
having avg_sal<2000;

查询结果

deptnoavg_sal
301566.6667

二、多表查询:跨表关联数据

先明确关联表基础数据:

dept部门表

deptnodnameloc
10accountingnew york
20researchdallas
30saleschicago
40operationsboston

salgrade工资级别表

gradelosalhisal
17001200
212011400
314012000
420013000
530019999

1. 基础多表联查(等值连接)

(1)查 “员工名、工资、所属部门名”

select emp.ename, emp.sal, dept.dname 
from emp, dept 
where emp.deptno = dept.deptno;

查询结果(节选):

enamesaldname
smith800research
allen1600sales
ward1250sales
jones2975research
martin1250sales
blake2850sales
clark2450accounting
scott3000research
king5000accounting
turner1500sales
adams1100research
james950sales
ford3000research
miller1300accounting

(2)限定部门号为 10的员工

select ename, sal, dname 
from emp, dept 
where emp.deptno=dept.deptno 
and dept.deptno=10;

查询结果

enamesaldname
clark2450accounting
king5000accounting
miller1300accounting

2. 三表联查(含工资级别表)

select ename, sal, grade 
from emp, salgrade 
where emp.sal between losal and hisal;

查询结果

enamesalgrade
smith8001
allen16003
ward12502
jones29754
martin12502
blake28504
clark24504
scott30004
king50005
turner15003
adams11001
james9501
ford30004
miller13002

三、自连接:同一张表查上下级

-- 别名leader代表领导,worker代表员工
select leader.empno, leader.ename 
from emp leader, emp worker 
where leader.empno = worker.mgr 
and worker.ename='ford';

查询结果

empnoename
7566jones

四、子查询:用查询结果当条件 / 临时表

1. 单行子查询(返回一条结果)

select ename, job 
from emp 
where sal = (select max(sal) from emp);

查询结果

enamejob
kingpresident

2. 多行子查询(返回多条结果)

(1)查 “和 10 号部门岗位相同、但不属于 10 号部门” 的员工

select ename,job,sal,deptno 
from emp 
where job in (select distinct job from emp where deptno=10) 
and deptno<>10;

查询结果

enamejobsaldeptno
jonesmanager297520
blakemanager285030
smithclerk80020
adamsclerk110020
jamesclerk95030

(2)查 “工资比 30 号部门所有员工都高” 的员工

select ename, sal, deptno 
from emp 
where sal > all(select sal from emp where deptno=30);

查询结果

enamesaldeptno
jones297520
scott300020
king500010
ford300020

3. from 子句子查询(把子查询当临时表)

-- 先查各部门平均工资(临时表tmp),再关联员工表
select ename, deptno, sal, format(tmp.avg_sal,2) as dept_avg_sal
from emp, 
(select avg(sal) avg_sal, deptno dt from emp group by deptno) tmp
where emp.sal > tmp.avg_sal 
and emp.deptno=tmp.dt;

查询结果

enamedeptnosaldept_avg_sal
king1050002,916.67
jones2029752,175.00
scott2030002,175.00
ford2030002,175.00
blake3028501,566.67
allen3016001,566.67

五、合并查询:union/union all

1. union(自动去重)

select ename, sal, job from emp where sal>2500 
union
select ename, sal, job from emp where job='manager';

查询结果(无重复数据):

enamesaljob
jones2975manager
blake2850manager
scott3000analyst
king5000president
ford3000analyst
clark2450manager

2. union all(保留重复)

select ename, sal, job from emp where sal>2500 
union all
select ename, sal, job from emp where job='manager';

查询结果(jones、blake 重复出现):

enamesaljob
jones2975manager
blake2850manager
scott3000analyst
king5000president
ford3000analyst
jones2975manager
blake2850manager
clark2450manager

总结

mysql 复合查询是实际开发的核心技能,核心是理清表关系、灵活组合单表 / 多表 / 子查询语法

本文所有示例均基于真实员工管理表数据,查询结果可直接验证,建议你复制 sql 语句在本地数据库中实操,更快掌握各类查询技巧~

这些仅为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

  • MySQL中的表操作及查询方式

    MySQL中的表操作及查询方式

    一.表操作mysql的操作中,一些专用的词无论是大写还是小写都是可以通过的。1.插入数据insert [into] table_name (列名称…)value... [阅读全文]
  • MySQL 存储引擎层常见问题详解

    MySQL 存储引擎层常见问题详解

    一、mysql 存储引擎层是什么?mysql 的存储引擎层(storage engine layer)是数据库系统中负责数据实际存储和检索的核心模块。它将 sq... [阅读全文]
  • MySQL死锁排查指南

    MySQL死锁排查指南

    mysql死锁排查指南作为一名10年经验的java工程师,我会从场景、排查、解决三个维度,带你搞定mysql死锁问题。一、先搞懂:死锁是什么?死锁是多个事务互相... [阅读全文]
  • MySQL表数据删除与清理的最佳实践

    在mysql运维中,“删除”操作看似简单,却隐藏着诸多风险——误删表导致数据永久丢失、delete全表引发主从延迟、删数据后磁盘空间…

    2025年12月25日 数据库
  • MySQL分页查询优化的实践指南

    引言在日常业务开发中,分页查询是高频操作,比如列表页数据展示、历史记录查询等。但当数据量达到万级以上时,普通的limit分页往往会出现性能瓶颈。本文基于实际测试场景,详细分析mys…

    2025年12月25日 数据库
  • MySQL全面解读数据类型及其影响分析

    前言上篇文章小编讲述了关于mysql表的ddl操作,在那里我多次使用了mysql的数据类型,但是我并没有去讲述mysql的数据类型,想必各位读者已经很好奇mysql的数据类型都有什…

    2025年12月29日 数据库

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com