文章目录
多表查询,也称为关联查询,指两个或更多个表一起完成的查询操作。这些一起查询的表通过关联字段关联,可能一对一,也可能一对多。
比如,要查询 last_name为’Abel’的员工在哪座城市工作?
SELECT department_id
FROM employees
WHERE last_name = 'Abel'; -- 查询到last_name为'Abel'时,其department_id是80
SELECT location_id
FROM departments
WHERE department_id = 80; -- 查询到department_id为80时,其location_id是2500
SELECT city
FROM locations
WHERE location_id = 2500; -- 查询到location_id为2500时,其city是Oxford
以上通过3步查询,终于得到了结果:last_name为’Abel’的员工在Oxford这座城市工作。
但是,如果使用 多表查询 则会简便很多。
接下来,我们会看到
- 多表查询的错误示范:多表查询时,出现了笛卡儿积。
- 多表查询的正确示范:
- 多表查询时,需要连接条件。
- 多表查询时,如果SELECT子句中出现了多个表中都存在的字段,则必须指明该字段所在表。
- 多表查询时,SELECT子句中出现的每个字段,建议都指明其所在表。
- 给表取别名,在SELECT或WHERE中使用表的别名。
- 给表取别名,在SELECT或WHERE中就必须使用表的别名,不能再使用表的原名了。
- 多表查询时,如果有N个表,则至少需要N-1个连接条件。
多表查询,出现了笛卡儿积
多表查询出现了笛卡儿积(或称为 交叉连接,CROSS JOIN)。
SELECT employee_id
FROM employees; -- 返回107条记录
SELECT department_name
FROM departments; -- 返回27条记录
SELECT employee_id,department_name
FROM employees,departments; -- 返回107 * 27 = 2889条记录
-- 每个员工把每个部门都匹配了一遍,即出现了笛卡儿积(笛卡儿积,也称为交叉连接,CROSS JOIN)。
# 等同于
SELECT employee_id,department_name
FROM employees CROSS JOIN departments; -- 返回107 * 27 条记录
-- 每个员工把每个部门都匹配了一遍,即出现了笛卡儿积(笛卡儿积,也称为交叉连接,CROSS JOIN)。
多表查询时,需要连接条件
# 多表查询时,需要连接条件
SELECT employee_id,department_name
FROM employees,departments
WHERE employees.department_id= departments.department_id;
多表查询时,如果SELECT子句中存在多个表中都存在的字段,则必须指明该字段所在表
# 多表查询时,如果SELECT子句中出现多个表中都存在的字段,则必须指明该字段所在表。
SELECT employee_id,department_name,department_id
FROM employees,departments
WHERE employees.department_id = departments.department_id; -- 报错:Column 'department_id' in field list is ambiguous
SELECT employee_id,department_name,employees.department_id
FROM employees,departments
WHERE employees.department_id = departments.department_id; -- 返回106条记录
多表查询时,SELECT子句中出现的字段,建议都指明其所在表(从sql优化的角度考虑)
# 多表查询时,SELECT子句中出现的字段,建议都指明其所在表。(从sql优化的角度考虑)
SELECT employees.employee_id,departments.department_name,departments.department_id
FROM employees,departments
WHERE employees.department_id = departments.department_id; -- 返回106条记录
给表取别名,在SELECT或WHERE中使用表的别名
# 给表取别名,在SELECT或WHERE中使用表的别名
SELECT e.employee_id,d.department_name,d.department_id
FROM employees e,departments d
WHERE e.department_id = d.department_id;
给表取了别名,SELECT或WHERE中必须使用表的别名,不能再使用表的原名了
# 给表取了别名,SELECT或WHERE中就必须使用表的别名,不能再使用表的原名了
SELECT employees.employee_id,d.department_name,d.department_id
FROM employees e,departments d
WHERE e.department_id = d.department_id; -- 报错:Unknown column 'employees.employee_id' in 'field list'
SELECT e.employee_id,d.department_name,d.department_id
FROM employees e,departments d
WHERE e.department_id = departments.department_id; -- 报错:Unknown column 'departments.department_id' in 'where clause'
多表查询时,如果有N个表,则至少需要N-1个连接条件
1. 查询员工的employee_id,last_name,department_name和city
# 查询员工的employee_id,last_name,department_name和city
SELECT e.employee_id,e.last_name,d.department_name,l.city
FROM employees e,departments d,locations l
WHERE e.department_id = d.department_id
AND d.location_id = l.location_id; -- 返回106条记录
2. 查询last_name为’Abel’的员工,其工作所在城市
# 查询last_name为'Abel'的员工,其工作所在城市
SELECT e.last_name,d.department_id,l.location_id,l.city
FROM employees e,departments d,locations l
WHERE e.department_id = d.department_id
AND d.location_id = l.location_id
AND e.last_name = 'Abel';
-- 返回数据如下
-- last_name department_id location_id city
-- Abel 80 2500 Oxford