SQL-第06章_多表查询

# 熟悉
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;


#2.多表的查询如何实现:

#出现笛卡尔积的错误:
#错误的原因:缺少了多表的连接条件

#错误的方式1:每个员工都和每个部门匹配了一遍:
SELECT employee_id,department_name
FROM employees,departments;#查询出2889条记录

#错误的方式2:CROSS JOIN
SELECT employee_id,department_name
FROM employees CROSS JOIN departments;#查询出2889条记录

SELECT *
FROM employees;#107行

SELECT 2889 / 107
FROM DUAL;

SELECT *
FROM departments;#27

#3#多表的查询实现:
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优化的角度,建议多表查询时,每个字段前都指明其所在的表.

#5 可以给表起别名:在SELECT 和 WHERE中使用表的别名:

#如果查询语句中出现了多个表中都存在的字段,则必须指明此字段所在的表
SELECT employee_id,department_name,emp.department_id
FROM employees emp,departments dept
#两个表的连接条件
WHERE emp.department_id = dept.department_id;
#如果给表起了别名,一旦在SELECT 和 WHERE中使用表名的话,就必须使用别名,不能再用原名.

#如果有n个表实现多表的查询,至少需要n-1个连接条件.
#6 练习:查询员工的employee_id,last_name,department_name,department_id
SELECT employee_id,last_name,department_name,city
FROM employees e, departments d,locations l
WHERE e.department_id = d.department_id AND d.location_id = l.location_id;

#7.多表查询的分类:
/*
角度1:等值连接 和 非等值连接

角度2:自连接 和 非自连接

角度3:内连接 和 外连接
*/

#7.1等值连接 vs 非等值连接

#非等值连接例子:
SELECT *
FROM job_grades;

#举例:
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;
WHERE  e.salary < j.highest_sal AND  e.salary > lowest_sal;

#7.2: 自连接 和 非自连接

SELECT * FROM employees;

#查询员工id 姓名及其管理者的id name
SELECT e.employee_id, e.last_name, m.employee_id, m.last_name
FROM employees e,employees m
WHERE e.manager_id = m.employee_id;


#7.3 : 内连接 和 外连接

#内连接:合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行

SELECT employee_id,department_name
FROM employees e,departments d
WHERE e.department_id = d.department_id;#只有106条记录

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

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

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

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

#练习:查询 所有 员工的last_name department_name信息

SELECT last_name, department_name
FROM employees e,departments d
WHERE e.department_id = d.department_id; # 需要使用左外连接

#SQL92语法实现内连接:见上,略.

#SQL92语法实现外连接:使用 +   ---------------MySQL不支持SQL92语法实现外连接
SELECT last_name, department_name
FROM employees e,departments d
WHERE e.department_id = d.department_id(+); 

#SQL99语法使用 JOIN...ON 的方式实现多表的查询.这种方式也能解决外连接的问题.MySQL支持.

#SQL99语法如何实现多表的查询:
SELECT last_name, department_name
FROM employees e,departments d
WHERE e.department_id = d.department_id(+); 

#SQL99语法实现内连接:
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语法实现外连接:
#练习:查询 所有 员工的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的方式!
SELECT last_name, department_name
FROM employees e FULL OUTER JOIN departments d
ON e.department_id = d.department_id;

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

#9.0 7种JOIN的实现:

#中图:内连接
SELECT employee_id, department_name
FROM employees e JOIN departments d
ON e.department_id = d.department_id;

#左上图:左外连接
SELECT employee_id, department_name
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id;

#右上图:右外连接
SELECT employee_id, department_name ,d.department_id,e.department_id
FROM employees e RIGHT JOIN departments d
ON e.department_id = d.department_id;

#左中图:
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 RIGHT JOIN departments d
ON e.department_id = d.department_id
WHERE e.department_id IS NULL;

#左下图:满外连接
#方式1:左上图 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;

#方式2:左中图 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
UNION ALL
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
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;

#10 SQL99语法的新特性1:自然连接
SELECT employee_id,last_name,department_name
FROM employees e JOIN departments d
ON e.`department_id` = d.`department_id`
AND e.`manager_id` = d.`manager_id`;

# NATURAL JOIN :。它会帮你自动查询两张连接表中所有相同的字段 ,然后进行等值连接 。
SELECT employee_id,last_name,department_name
FROM employees e NATURAL JOIN departments d

#11 SQL99语法的新特性2:USING
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 JOIN departments d
USING(department_id);

SELECT * FROM employees;
SELECT * FROM departments;

#所有有奖金的员工的last_name   department_name department_id l.city
SELECT e.last_name,e.commission_pct,d.department_name,d.location_id,l.city
FROM employees e LEFT JOIN departments d
ON e.department_id = d.department_id
LEFT JOIN locations l
ON d.location_id = l.location_id
WHERE e.commission_pct IS NOT NULL;

猜你喜欢

转载自blog.csdn.net/m0_63104578/article/details/126123191