多表查询

多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。 前提条件:这些一起查询的表之间是有关系的(一对一、一对多),它们之间一定是有关联字段,这个 关联字段可能建立了外键,也可能没有建立外键。比如:员工表和部门表,这两个表依靠“部门编号”进 行关联。

笛卡尔积

笛卡尔乘积是一个数学运算。假设我有两个集合 X 和 Y,那么 X 和 Y 的笛卡尔积就是 X 和 Y 的所有可能 组合,也就是第一个对象来自于 X,第二个对象来自于 Y 的所有可能。组合的个数即为两个集合中元素 个数的乘积数。

编写 SQL 的函数

-- 使用 join
SELECT * FROM a JOIN b;
SELECT * FROM a,b;
SELECT * FROM a INNER JOIN b;
-- SQL99
SELECT * FROM a CROSS JOIN b;

笛卡尔积的错误产生的条件是

  1. 省略多个表的连接条件(或关联条件)

  2. 连接条件(或关联条件)无效

  3. 所有表中的所有行互相连接

为了避免笛卡尔积,可以在 WHERE 或 on 加入有效的连接条件。

加入连接条件后,查询语法:

SELECT table1.column, table2.column
FROM table1, table2
WHERE table1.column1 = table2.column2; #连接条件
# 或
SELECT table1.column, table2.column
FROM table1 INNER JOIN table2
ON table1.column1 = table2.column2

七种SQL JOINS的实现

交集: 中图

SELECT employee_id, last_name, department_name
FROM employees e JOIN departments d
ON e.department_id = d.department_id;

左外连接: 左上图

SELECT employee_id, last_name, department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id;

右外连接: 右上图

SELECT employee_id, last_name, department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id;

A - A∩B: 左中图

select 字段列表
from A表 left join B表
on 关联条件
where 从表关联字段 is null and 等其他子句;
SELECT employee_id, last_name, department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id is null;

B-A∩B: 右中图

#实现B - A∩B
select 字段列表
from A表 right join B表
on 关联条件
where 从表关联字段 is null and 等其他子句;
SELECT employee_id,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL

左下图

#实现查询结果是A∪B
#用左外的A,union 右外的B
select 字段列表
from A表 left join B表
on 关联条件
where 等其他子句
union
select 字段列表
from A表 right join B表
on 关联条件
where 等其他子句;
SELECT employee_id, last_name, department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL
UNION ALL
SELECT employee_id, last_name, department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id;

右下图

select 字段列表
from A表 left join B表
on 关联条件
where 从表关联字段 is null and 等其他子句
union
select 字段列表
from A表 right join B表
on 关联条件
where 从表关联字段 is null and 等其他子句
SELECT employee_id, last_name, department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL
UNION ALL
SELECT employee_id, last_name, department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE e.department_id IS NULL;