Jw
首页
技术
英语
首页
技术
英语
  • MySQL

    • MySQL 基础
    • 环境变量配置(PATH)
    • SQL 语法与分类
    • MySQL 数据类型
    • SQL - DDL 数据定义语言
    • SQL - DML 数据操作语言
    • SQL - DQL 数据查询语言
    • SQL - DCL 数据控制语言
    • MySQL 函数
    • SQL 约束
    • SQL 外键约束
    • 多表关系
    • 多表查询(连接查询)
    • 隐式内连接 vs 显式内连接
    • 子查询
    • 多表查询案例
    • 事务
    • 并发事务问题与隔离级别
    • MySQL 体系结构与存储引擎
    • 索引概述
    • 索引结构
    • 索引分类
    • 索引语法
    • SQL 性能分析
    • 索引使用
    • 索引设计原则
    • SQL 优化 - 插入数据与主键优化
    • SQL 优化 - order by 与 group by
    • SQL 优化 - limit / count / update
    • 视图
    • 存储过程
    • 存储过程 - 变量
    • 存储过程 - 流程控制、游标与条件处理
    • 存储函数
    • 触发器
    • 锁概述与全局锁
    • 表级锁
    • 行级锁
    • InnoDB 逻辑存储结构
    • InnoDB 架构
    • 事务原理(redo / undo log)
    • MVCC
    • MySQL 系统数据库
    • MySQL 常用工具
    • 数据备份与导入导出
    • 错误日志与二进制日志
    • 查询日志与慢查询日志
    • 主从复制 - 概述与原理
    • 主从复制 - 搭建
    • Mycat 配置
    • Mycat 垂直拆分与水平拆分
    • Mycat 分片规则
    • Mycat 管理与监控
    • Mycat 读写分离 - 一主一从
    • Mycat 读写分离 - 双主双从

多表查询案例

12 道多表查询综合练习(连接查询 + 子查询),示例数据沿用 多表查询 的 emp / dept 表。

补充:薪资等级表 salgrade

CREATE TABLE salgrade(
    grade  INT,   -- 等级
    losal  INT,   -- 最低薪资
    hisal  INT    -- 最高薪资
) COMMENT '薪资等级表';

INSERT INTO salgrade VALUES
(1, 0, 3000), (2, 3001, 5000), (3, 5001, 8000), (4, 8001, 10000),
(5, 10001, 15000), (6, 15001, 20000), (7, 20001, 25000), (8, 25001, 30000);

薪资落在 [losal, hisal] 区间内,用 BETWEEN ... AND ... 关联等级表。

一、练习题

  1. 查询员工的姓名、年龄、职位、部门信息。
  2. 查询年龄小于 30 岁的员工姓名、年龄、职位、部门信息。
  3. 查询拥有员工的部门 ID、部门名称。
  4. 查询所有年龄大于 40 岁的员工,及其归属的部门名称;如果员工没有分配部门,也需要展示出来。
  5. 查询所有员工的工资等级。
  6. 查询"研发部"所有员工的信息及工资等级。
  7. 查询"研发部"员工的平均工资。
  8. 查询工资比"灭绝"高的员工信息。
  9. 查询比平均薪资高的员工信息。
  10. 查询低于本部门平均工资的员工信息。
  11. 查询所有的部门信息,并统计部门的员工人数。
  12. 查询所有学生的选课情况,展示出学生名称、学号、课程名称。

二、参考答案

-- 1. 员工 + 部门(隐式内连接)
SELECT e.name, e.age, e.job, d.name FROM emp e, dept d WHERE e.dept_id = d.id;

-- 2. 年龄小于 30 岁的员工 + 部门(显式内连接)
SELECT e.name, e.age, e.job, d.name FROM emp e INNER JOIN dept d ON e.dept_id = d.id WHERE e.age < 30;

-- 3. 有员工的部门(DISTINCT 去重)
SELECT DISTINCT d.id, d.name FROM dept d JOIN emp e ON d.id = e.dept_id;

-- 4. 年龄大于 40 的员工 + 部门,没有部门的也要展示(左外连接)
SELECT e.*, d.name FROM emp e LEFT JOIN dept d ON e.dept_id = d.id WHERE e.age > 40;

-- 5. 所有员工的工资等级
SELECT e.*, s.grade FROM emp e LEFT JOIN salgrade s ON e.salary BETWEEN s.losal AND s.hisal;

-- 6. 研发部员工的信息及工资等级
SELECT e.*, s.grade FROM emp e
    LEFT JOIN salgrade s ON e.salary BETWEEN s.losal AND s.hisal
    WHERE e.dept_id = (SELECT id FROM dept WHERE name = '研发部');

-- 7. 研发部员工的平均工资
SELECT AVG(e.salary) FROM emp e
    WHERE e.dept_id = (SELECT id FROM dept WHERE name = '研发部');

-- 8. 工资比"灭绝"高的员工(标量子查询)
SELECT * FROM emp WHERE salary > (SELECT salary FROM emp WHERE name = '灭绝');

-- 9. 工资高于全公司平均工资的员工
SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp);

-- 10. 低于本部门平均工资的员工(相关子查询:内外层用同一个 dept_id)
SELECT * FROM emp e1
    WHERE e1.salary < (SELECT AVG(e2.salary) FROM emp e2 WHERE e2.dept_id = e1.dept_id);

-- 11. 所有部门及其员工人数(SELECT 之后的子查询)
SELECT d.*, (SELECT COUNT(*) FROM emp WHERE dept_id = d.id) '人数' FROM dept d;

-- 12. 学生选课情况(三表联查:学生、中间表、课程)
SELECT s.name, s.no, c.name FROM student s, student_course sc, course c
    WHERE s.id = sc.studentid AND sc.courseid = c.id;

三、要记住的套路

需求特征做法
只要两表都匹配的数据内连接(隐式 / 显式)
主表数据全部保留左外 / 右外连接(LEFT JOIN + IS NULL 也能找「没有关联数据」的行)
查同一张表的层级关系(员工-领导)自连接 + 表别名
过滤条件是一个值标量子查询(= / > 等)
过滤条件是一列列子查询(IN / ANY / ALL)
过滤条件是一行多列行子查询((字段1, 字段2) = (SELECT ...))
子查询结果当表用表子查询放在 FROM 之后并起别名
与本部门 / 本行数据比较相关子查询(内外层用同名字段关联)

相关

  • 多表查询(连接查询):示例数据与连接语法
  • 子查询:四类子查询
  • 多表关系:一对多 / 多对多 / 一对一
最近更新: 2026/10/9 13:59
Contributors: liujw
Prev
子查询
Next
事务