热门课程 - 发现知识之美

MySQL 数据库

作者: 蒋老师 更新: 2025-12-08 阅读: 难度: 高级
学习工具

. 多表连接查询

在实际应用中,数据通常分布在多个表中,连接查询是获取相关数据的关键技术。

连接类型概述

  • INNER JOIN:内连接,返回两个表中匹配的记录
  • LEFT JOIN:左连接,返回左表所有记录和右表匹配记录
  • RIGHT JOIN:右连接,返回右表所有记录和左表匹配记录
  • FULL OUTER JOIN:全外连接(MySQL不支持,需用UNION模拟)
  • CROSS JOIN:交叉连接,返回笛卡尔积

创建示例数据

准备测试数据
-- 员工表 CREATE TABLE employees ( emp_id INT PRIMARY KEY, emp_name VARCHAR(50), dept_id INT, salary DECIMAL(10,2) ); -- 部门表 CREATE TABLE departments ( dept_id INT PRIMARY KEY, dept_name VARCHAR(50), location VARCHAR(100) ); -- 插入数据 INSERT INTO departments VALUES (1, '技术部', '北京'), (2, '市场部', '上海'), (3, '人事部', '广州'), (4, '财务部', '深圳'); INSERT INTO employees VALUES (101, '张三', 1, 15000.00), (102, '李四', 1, 18000.00), (103, '王五', 2, 12000.00), (104, '赵六', 2, 14000.00), (105, '钱七', NULL, 16000.00), (106, '孙八', 5, 13000.00); -- 部门ID不存在

INNER JOIN内连接

内连接示例
-- 基本内连接 SELECT e.emp_id, e.emp_name, e.salary, d.dept_name, d.location FROM employees e INNER JOIN departments d ON e.dept_id = d.dept_id; -- 多表内连接 -- 假设有第三个表:项目表 projects CREATE TABLE projects ( project_id INT PRIMARY KEY, project_name VARCHAR(100), emp_id INT ); INSERT INTO projects VALUES (1, '电商系统开发', 101), (2, '移动App开发', 102), (3, '市场推广活动', 103); -- 三表连接 SELECT e.emp_name, d.dept_name, p.project_name FROM employees e INNER JOIN departments d ON e.dept_id = d.dept_id INNER JOIN projects p ON e.emp_id = p.emp_id; -- 带条件的连接 SELECT e.emp_name, e.salary, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id = d.dept_id WHERE e.salary > 13000 ORDER BY e.salary DESC;

LEFT JOIN左连接

左连接示例
-- 左连接:所有员工,包括没有部门的 SELECT e.emp_id, e.emp_name, COALESCE(d.dept_name, '未分配') AS dept_name, COALESCE(d.location, '未知') AS location FROM employees e LEFT JOIN departments d ON e.dept_id = d.dept_id; -- 查找没有部门的员工 SELECT e.emp_id, e.emp_name, e.salary FROM employees e LEFT JOIN departments d ON e.dept_id = d.dept_id WHERE d.dept_id IS NULL; -- 左连接统计每个部门员工数 SELECT d.dept_name, COUNT(e.emp_id) AS employee_count FROM departments d LEFT JOIN employees e ON d.dept_id = e.dept_id GROUP BY d.dept_id, d.dept_name ORDER BY employee_count DESC; -- 员工和项目左连接(员工可能有多个项目) SELECT e.emp_name, p.project_name FROM employees e LEFT JOIN projects p ON e.emp_id = p.emp_id;

其他连接类型

右连接和自连接
-- RIGHT JOIN右连接 SELECT d.dept_name, e.emp_name FROM employees e RIGHT JOIN departments d ON e.dept_id = d.dept_id; -- 查找没有员工的部门 SELECT d.dept_name, d.location FROM departments d LEFT JOIN employees e ON d.dept_id = e.dept_id WHERE e.emp_id IS NULL; -- 自连接:员工和经理关系 ALTER TABLE employees ADD COLUMN manager_id INT; UPDATE employees SET manager_id = 101 WHERE emp_id IN (102, 103); UPDATE employees SET manager_id = 103 WHERE emp_id = 104; -- 查询员工及其经理 SELECT e.emp_name AS employee_name, m.emp_name AS manager_name FROM employees e LEFT JOIN employees m ON e.manager_id = m.emp_id; -- CROSS JOIN交叉连接 SELECT e.emp_name, d.dept_name FROM employees e CROSS JOIN departments d LIMIT 10; -- 模拟FULL OUTER JOIN SELECT e.emp_name, d.dept_name FROM employees e LEFT JOIN departments d ON e.dept_id = d.dept_id UNION SELECT e.emp_name, d.dept_name FROM employees e RIGHT JOIN departments d ON e.dept_id = d.dept_id;
提示: 这是一个重要的概念,需要特别注意理解和掌握。
注意: 这是一个常见的错误点,请避免犯同样的错误。

评论

登录 后发表评论