5.2 自连接 vs 非自连接
5.2.1 自连接
一张表,自己与自己进行连接。用取别名的方式虚拟成两张表以代表不同的意义。然后两个表再进行内连接,外连接等查询。
自连接的例子:
查询员工id,员工姓名及其管理者的id和姓名
# 查询员工id,员工姓名及其管理者的id和姓名 SELECT e.employee_id, e.last_name, m.employee_id FROM employees e, employees m WHERE e.manager_id = m.employee_id
5.2.2 非自连接
一张表与另一张表进行连接查询。
非自连接的例子:
查询员工的工资等级:
SELECT employees.last_name, employees.salary, job_grades.grade_level FROM employees, job_grades WHERE employees.salary BETWEEN job_grades.lowest_sal AND job_grades.highest_sal;
5.3 内连接
内连接:合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行,即内连接的查询结果集中都是两张表中能够相互匹配的记录根据连接条件组成的结果,不存在一个表中有的记录而另一张表中没有与之相匹配的记录组成的结果。
查询员工编号及其所在的部门:
SELECT employee_id,department_name FROM employees e,departments d WHERE e.`department_id` = d.department_id;
不包含没有部门的员工
SQL92语法实现内连接:见上,略
SQL99语法中使用 JOIN …ON 的方式实现多表的查询。
SQL99语法实现内连接:
两张表:
SELECT last_name, department_name FROM employees INNER JOIN departments ON employees.department_id = departments.department_id;
三张表:
SELECT last_name, department_name, city FROM employees INNER JOIN departments ON employees.department_id = departments.department_id INNER JOIN locations ON departments.location_id = locations.location_id;
5.4 外连接
外连接:合并具有同一列的两个以上的表的行, 结果集中除了包含一个表与另一个表匹配的行之外,还查询到了左表 或 右表中不匹配的行。
外连接的分类:
- 左外连接
两个表在连接过程中除了返回满足连接条件的行以外还返回左表中不满足条件的行,这种连接称为左外连接。 - 右外连接
两个表在连接过程中除了返回满足连接条件的行以外还返回右表中不满足条件的行,这种连接称为右外连接。 - 满外连接
左外连接与右外连接的并集
5.4.1 使用(+)实现外连接
SQL92语法实现外连接:使用 + ---------- MySQL不支持SQL92语法中外连接的写法!
查询所有的员工的last_name,department_name信息 :
需要使用左外连接
使用SQL92:(MySQL不支持)
SELECT employee_id,department_name FROM employees e,departments d # 需要完全保留的表 对应的另一张表 使用(+) # 相当于使用(+)对于数据的少的表使用 Null 进行补全 WHERE e.`department_id` = d.department_id(+);
5.4.1 SQL99外连接
SQL99语法中使用 JOIN …ON 的方式实现多表的查询。这种方式也能解决外连接的问题。MySQL是支持此种方式的。
LEFT JOIN 和 RIGHT JOIN 只存在于 SQL99 及以后的标准中,在 SQL92 中不存在,只能用 (+) 表示。
使用SQL99实现外连接:
查询所有的员工的last_name, department_name信息
5.4.2 左外连接
SELECT last_name, department_name FROM employees e LEFT OUTER JOIN departments d ON e.department_id=d.department_id; # outer 可以省略 SELECT last_name, department_name FROM employees e LEFT JOIN departments d ON e.department_id=d.department_id;
5.4.3 右外连接
SELECT last_name, department_name FROM employees e RIGHT JOIN departments d ON d.department_id = e.department_id;
5.4.4 满外连接
- 满外连接的结果 = 左右表匹配的数据 + 左表没有匹配到的数据 + 右表没有匹配到的数据。
- SQL99是支持满外连接的。使用FULL JOIN 或 FULL OUTER JOIN来实现。
- 需要注意的是,MySQL不支持FULL JOIN,但是可以用 LEFT JOIN UNION RIGHT JOIN 代替。
mysql不支持FULL OUTER JOIN:
SELECT last_name, department_name FROM employees e FULL OUTER JOIN departments d ON d.department_id = e.department_id;