# 多表查询
# 出现笛卡尔积的错误
SELECT employee_id,department_name
from employees,departments;
#错误
SELECT employee_id,department_name
from employees CROSS JOIN departments;
# 多表查询需要有连接条件
SELECT employee_id,department_name
from employees,departments
WHERE employees.department_id = departments.department_id;
# 查询语句中出现了多个表中都存在的字段,则必须指名此字段所在的表
SELECT employee_id,department_name,employees.department_id
from employees,departments
WHERE employees.department_id = departments.department_id;
# 建议:从sql优化的角度,多表表查询时,每个字段都指名其所在的表。
# 可以给表起别名,在SELECT和WHERE中使用别名
SELECT emp.employee_id,dep.department_name,emp.department_id
from employees emp,departments dep
WHERE emp.`department_id` = dep.department_id;
# 非等价连接
SELECT e.last_name,e.salary,j.grade_level
FROM employees e,job_grades j
WHERE e.salary >= j.lowest_sal && e.salary<=j.highest_sal;
# 自连结
SELECT emp.employee_id,emp.last_name,mgr.employee_id,mgr.last_name
FROM employees emp,employees mgr
WHERE emp.manager_id = mgr.employee_id;
内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行
SELECT employee_id,department_name
FROM employees e,departments d
WHERE e.department_id = d.department_id; # 只有106条记录
外连接:合并具有同一列的两个以上的表的运行,结果集中除了包好一个表与另一个表匹配的行之外,还查询到了左表与右表中不匹配的行。
# 外连接的分类:左外连接,右外连接,满外连接
SELECT employee_id,department_name
FROM employees e,departments d
WHERE e.department_id = d.department_id(+); # SQL92写法,Mysql不支持
# SQL99语法内连接 JOIN ... ON ...
SELECT employee_id,department_name
FROM employees e JOIN departments d
ON e.department_id = d.department_id;
SELECT employee_id,department_name,city
FROM employees e JOIN departments d
ON e.department_id = d.department_id
JOIN locations l
ON d.location_id = l.location_id;
# SQL99外连接
# 左外连接
SELECT last_name,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id;
# 右外连接
SELECT last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id;
# 满外连接 mysql不支持 FULL OUTER JOIN
SELECT last_name,department_id
FROM employees e FULL OUTER JOIN departments d
ON e.department_id = d.department_id;
# UNION:回去重
# UNION ALL:不去重
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
UNION ALL
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE e.department_id IS NULL;
SELECT employee_id,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
UNION ALL
SELECT employee_id,department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
WHERE d.department_id IS NULL;
SELECT employee_id,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,department_name
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE e.department_id IS NULL;