IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 大数据 -> MySQL学习之多表查询 -> 正文阅读

[大数据]MySQL学习之多表查询

#第06章_多表查询
#1.熟悉常见的几个表
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.多表查询如何实现


#2.1出现笛卡尔积的错误
#错误的实现方式:每个员工都与每个部门匹配了一遍
#错误的原因:缺少了多表的连接条件
SELECT employee_id,department_name
FROM employees,departments;#2889条记录
#错误的实现方式:
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 employees.employee_id,departments.department_name,employees.`department_id`
FROM employees,departments
WHERE employees.`department_id`=departments.`department_id`;

#建议:从sql优化的角度,建议多表查询时,每个字段都指明其所在的表

#5.可以给表起别名,在SELECT和WHERE中使用别名
SELECT emp.employee_id,dept.department_name,emp.`department_id`
FROM employees emp,departments dept
WHERE emp.`department_id`=dept.`department_id`;

#如果给表起了别名,一旦在SELECT或WHERE中使用表名的话,则必须使用表的别名,而不能再使用表的原名。
#如下的操作是错误的:
SELECT emp.employee_id,dept.department_name,emp.`department_id`
FROM employees emp,departments dept
WHERE emp.`department_id`=departments.`department_id`;

#6.结论:如果有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`

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

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

角度三: 内连接    vs  外连接
*/

#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.`lowest_sal`and e.`salary`<=j.`highest_sal`;

#7.2自连接    vs  非自连接

#自连接的例子:
#练习:查询员工id,员工姓名及其管理者的id和姓名
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条记录

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

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

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

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

SELECT employee_id,department_name
FROM employees e,departments d
WHERE e.`department_id`=d.`department_id`;#需要使用左外连接,MySQL不持支SQL92外连接的写法!
#不支持!
#SQL92语法实现内连接:见上
#SQL92语法实现外连接:使用 +
SELECT employee_id,department_name
FROM employees e,departments d
WHERE e.department_id=d.department_id(+);

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

#SQL99语法实现内连接:
SELECT last_name,department_name
FROM employees e inner 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 JOIN departments d
ON e.`department_id`=d.`department_id`;

#满外连接:mysql不支持FULL OUTER JOIN
SELECT last_name,department_name
FROM employees e full OUTER JOIN departments d
ON e.`department_id`=d.`department_id`;

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

#9. 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
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 last_name,job_title,department_name
FROM employees INNER JOIN departments INNER JOIN jobs
ON employees.department_id = departments.department_id
AND employees.job_id = jobs.job_id;

#练习题:

# 1.显示所有员工的姓名,部门号和部门名称。
select e.last_name,e.department_id,d.department_name
from employees e left outer join departments d
on e.`department_id`=d.`department_id`;
# 2.查询90号部门员工的job_id和90号部门的location_id
select job_id,location_id
from employees e,departments d
where e.`department_id`=d.`department_id`
and e.`department_id`=90;

# 3.选择所有有奖金的员工的 last_name , department_name , location_id , 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 l.`location_id`=d.`location_id`
where e.`commission_pct` is  not null

# 4.选择city在Toronto工作的员工的 last_name , job_id , department_id , department_name
select e.last_name , e.job_id , e.department_id , d.department_name
from employees e join departments d
on e.`department_id`=d.`department_id`
join locations l
on d.`location_id`=l.`location_id`
where l.`city`='Toronto';
#sql92语法:
SELECT e.last_name , e.job_id , e.department_id , d.department_name
FROM employees e,departments d,locations l
where e.`department_id`=d.`department_id`
and d.`location_id`=l.`location_id`
and l.`city`='Toronto';

# 5.查询员工所在的部门名称、部门地址、姓名、工作、工资,其中员工所在部门的部门名称为’Executive’
select d.department_name,l.street_address,e.last_name,e.job_id,e.salary
from departments d left join employees e
on e.`department_id`=d.`department_id`
left join locations l
on d.`location_id`=l.`location_id`
where d.`department_name`='Executive';

# 6.选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式
# employees Emp# manager Mgr#
# kochhar 101 king 100

select emp.last_name "employees",emp.employee_id "Emp#",mgr.last_name "manager",mgr.employee_id "Mgr#"
from employees emp left join employees mgr
on emp.manager_id=mgr.employee_id;
# 7.查询哪些部门没有员工

select d.department_id
from departments d left join employees e
on d.`department_id`=e.`department_id`
where e.`department_id` is null;

#本题也可以使用子查询

# 8. 查询哪个城市没有部门
select l.location_id,l.city
from locations l left join departments d
on l.`location_id`= d.`location_id`
where d.`location_id` is null;

# 9. 查询部门名为 Sales 或 IT 的员工信息
select e.employee_id,e.last_name,e.department_id
from employees e join departments d
on e.`department_id`=d.`department_id`
where d.`department_name`IN('Sales','IT')

  大数据 最新文章
实现Kafka至少消费一次
亚马逊云科技:还在苦于ETL?Zero ETL的时代
初探MapReduce
【SpringBoot框架篇】32.基于注解+redis实现
Elasticsearch:如何减少 Elasticsearch 集
Go redis操作
Redis面试题
专题五 Redis高并发场景
基于GBase8s和Calcite的多数据源查询
Redis——底层数据结构原理
上一篇文章      下一篇文章      查看所有文章
加:2022-05-21 19:02:54  更:2022-05-21 19:05:16 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 20:07:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码