数据库
首页 > 数据库> > MySQL04-多表查询

MySQL04-多表查询

作者:互联网

#04 多表查询
#常用表
DESC employees;

DESC departments;

DESC locations;

#查询员工名为'Abel'的人在哪个城市工作?
SELECT *
FROM employees
WHERE last_name = 'Abel';

SELECT *
FROM departments
WHERE department_id = 80;

SELECT *
FROM locations
WHERE location_id = 2500;

#1.多表查询的实现--关联查询

#错误实现,交叉连接(笛卡尔积)
SELECT employee_id,department_name
FROM employees,departments; #查询出2889条记录

#··需要在以上基础添加,多表的连接条件
SELECT employee_id,department_name
FROM employees,departments
WHERE employees.`department_id` = departments.`department_id`;

#··错误代码: 1052
#Column 'department_id' in field list is ambiguous(不明确的)
SELECT employee_id,department_name,department_id
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 employee_id,department_name,emp.department_id,dept.`department_name`
FROM employees emp,departments dept
WHERE emp.`department_id` = dept.`department_id`;

#**一旦给表起了别名,一旦在SELECT和WHERE中使用表名的话,则必须使用表的别名,而不能再用表的原名。
#Unknown column 'employees.department_id' in 'where clause'
SELECT employee_id,department_name,emp.department_id,dept.`department_name`
FROM employees emp,departments dept
WHERE employees.`department_id` = departments.`department_id`;

#结论:如果有n个表实现多表的查询,则需要至少n-1个连接条件
#查询员工的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`

#2.多表查询的分类
/*
角度一:等值连接 vs 非等值连接

角度二:自连接 vs 非自连接

角度三:内连接 vs 外连接

*/

#2.1 等值连接 vs 非等值连接
#非等值连接 例子
SELECT e.last_name,e.salary,j.grade_level
FROM employees e,job_grades j
WHERE e.`salary` BETWEEN j.`lowest_sal` AND j.`highest_sal`

#2.2 自连接 vs 非自连接
#自连接 例子
#查询员工id及上司的id和姓名
SELECT e.`last_name`,e.`employee_id`,m.`employee_id`,m.`last_name`
FROM employees e,employees m
WHERE e.`manager_id` = m.employee_id;

#2.3 内连接与外连接

#内连接--合并具有同一列的两个以上的表的行,结果集中不包含一个表和另一个表不匹配的行
SELECT employee_id,department_name
FROM employees e,departments d
WHERE e.`department_id` = d.`department_id`;

#外连接--合并具有同一列的两个以上的表的行,结果集中除了包含一个表和另一个表匹配的行
# 还查询到了左表或右表中不匹配的行

#外连接的分类:左外连接、右外连接、满外连接

#左(右)外连接:两个表在连接过程中除了返回满足连接条件的行以外,
# 还返回左(右)表中不满足条件的行,这种连接方式称为左(右)外连接

#查询所有员工的last_name和department_name信息

#SQL92语法实现外连接:使用+ 内连接实现如上,略
#但MySQL不支持SQL92外连接语法!ERROR
SELECT e.`last_name`,d.`department_name`
FROM employees e,departments d
WHERE e.`department_id` = d.`department_id`(+);

#SQL99语法如何实现多表查询, MySQL支持,7种join

#SQL99语法实现内连接:JOIN ON
SELECT last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`;

SELECT last_name,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语法实现外连接:LEFT (OUTER) JOIN ON

#左外连接,查询所有员工的last_name和department_name信息
SELECT last_name,department_name
FROM employees e LEFT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`;

#右外连接
SELECT last_name,department_name
FROM employees e RIGHT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`;

#满外连接:MySQL不支持FULL OUTER JOIN ON方法

SELECT last_name,department_name
FROM employees e FULL OUTER JOIN departments d
ON e.`department_id` = d.`department_id`;


#2.4 UNION 、UNION ALL 操作符

#UNION:会执行去重操作
#UINION ALL:不会执行去重操作
#结论:如果明确知道合并数据后的结果数据不存在重复数据,或者不需要去除重复的数据
# 则尽量使用UNION ALL语句,以提高数据查询的效率

#7种JOIN的实现:

#1. 内连接:取相同部分
SELECT employee_id,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`;

#2. 左外连接:相同部分+左表选中 左上图
SELECT employee_id,department_name
FROM employees e LEFT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`;

#3. 右外连接:相同部分+右表选中 右上图
SELECT employee_id,department_name
FROM employees e RIGHT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`;

#4. 左外连接减去相同部分 左中图
SELECT employee_id,department_name
FROM employees e LEFT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL;

#5. 右外连接减去相同部分 右中图
SELECT employee_id,department_name
FROM employees e RIGHT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL;

#6. 满外连接:右外连接+左外连接-一个重复部分

#方式一:左上图 UNION ALL 右中图
SELECT employee_id,department_name
FROM employees e LEFT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`
UNION ALL
SELECT employee_id,department_name
FROM employees e RIGHT OUTER JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL;

#方式二:左中图 UNION ALL 右上图
SELECT employee_id,department_name
FROM employees e LEFT OUTER 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 OUTER JOIN departments d
ON e.`department_id` = d.`department_id`;

#7. 右外连接+左外连接减去所有重复部分
#左中图 UNION ALL 右中图
SELECT employee_id,department_name
FROM employees e LEFT OUTER 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 OUTER JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL;





标签:MySQL04,多表,name,employees,departments,查询,department,id,SELECT
来源: https://www.cnblogs.com/Yehuw-blogs/p/16082879.html