MySql(9)多表查询

Mysql专栏入口

链接:https://pan.baidu.com/s/1zAhDUNv-yuJiWmaFLvTk4w
提取码:ttst
提取码:ttst
专栏中有mysql的导入导出,里面有教如何导入

从这章开始使用新的数据库记得切换

一、多表查询

为什么要多表查询?
练习:查询员工名为’Abel’的人在哪个城市工作

1.1 单查询

首先我需要在员工表中查询这个人的部门

SELECT * FROM employees WHERE last_name = 'Abel';

这时就查到了这个人的部门id
在这里插入图片描述
知道部门号后在从部门表中查询其地点id

SELECT * FROM departments WHERE department_id = 80;

在这里插入图片描述
知道地点id后再地点表中查询地点

SELECT * FROM locations WHERE location_id = 2500;

在这里插入图片描述
我们需要三个表employees、departments、locations才能找出我们需要的数据

1.2 多表查询

我们一步一步来首先查询一下员工姓名和所在的部门名称

这个写法 缺失了连接条件 所以是错误的 这错误有个名字,叫做笛卡儿积

SELECT last_name,department_name FROM employees,departments

更具上方sql添加入连接条件这样就正确了

SELECT
	last_name,
	department_name 
FROM
	employees,
	departments 
WHERE
	employees.department_id = departments.department_id

额外讲一下别名 取公共字段的时候需要将别名加上确定取哪个表里的值

SELECT
	last_name,
	department_name,
	d.department_id
FROM
	employees as e,
	departments as d
WHERE
	e.department_id = d.department_id

这时候我们就成功的把两个表连接了起来。那么我们来连接一下三张表如以下代码。

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

最后不要忘了,我们最终的目的是查询员工名为’Abel’的人在哪个城市工作。只需要再where里添加一个新的条件就可以了

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 AND e.last_name = "Abel"

二、各类连接概念

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
	emp.employee_id,
	emp.last_name,
	mgr.employee_id,
	mgr.last_name 
FROM
	employees emp,
	employees mgr 
WHERE
	emp.manager_id = mgr.employee_id

2.3 内连接 vs 外连接

我们之前使用的都是sql92规则 在这里我们使用sql99规则方便讲解

内连接:取出两个表都存在的记录。

SELECT
	employee_id,
	department_name 
FROM
	employees e
	JOIN departments d ON e.department_id = d.department_id

# 修改为sql99规则后我们如何做到三表连接
SELECT
	employee_id,
	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

外连接:以某一个表(左/右)为主(左表有但右表没有,反之也成立。),取出记录。外连接又分为常见的两种和不常见的四种.

常见 左连接/右连接

左连接(left join)

SELECT
	employee_id,
	department_name 
FROM
	employees e
	LEFT JOIN departments d ON e.department_id = d.department_id

右连接(right join)

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

满外连接

满外连接就是,左边独有的我要,左右都有的我要,右边独有的我也要!
这时要借助俩关键字,UNION ALL 和 UNION

假设两个表,左边独有的记录数量 1 公共部分 106 右边独有的 16

那么UNION ALL(推荐使用)在连接的时候会这样计算, (左) 1+106 + (右) 106 + 16 不会进行去重操作所以会加快速度,减少运算流程。

使用UNION时计算是这样的,1 + 106 +16,会进行去重操作,降低了运算速度。

而满外连接可以使用 左连接表 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
	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

三、小练习

1.所有有部门的人员信息

SELECT
	employee_id,
	last_name 
FROM
	employees e
	JOIN departments d ON e.department_id = d.department_id

2.列出所有用户,并显示其部门信息

SELECT
	e.employee_id,
	e.last_name,
	d.department_name
FROM
	employees e
	left JOIN departments d ON e.department_id = d.department_id

3.列出所有的部门

SELECT
	d.department_name,
	d.department_id
FROM
	employees e
	right JOIN departments d ON e.department_id = d.department_id

4.所有不入部门的人

SELECT
	d.department_name,
	d.department_id,
	e.last_name
FROM
	employees e
	left JOIN departments d ON e.department_id = d.department_id
WHERE
	d.department_id is NULL

5.所有没人入的部门

SELECT
	d.department_name,
	d.department_id,
	e.employee_id
FROM
	employees e
	right JOIN departments d ON e.department_id = d.department_id
	WHERE e.employee_id is NULL

6.列出所有人员和部门的对照关系

SELECT
	e.employee_id,
	e.last_name,
	d.department_name,
	d.department_id
FROM
	employees e
	left JOIN departments d ON e.department_id = d.department_id

UNION all

SELECT
	e.employee_id,
	e.last_name,
	d.department_name,
	d.department_id
FROM
	employees e
	right JOIN departments d ON e.department_id = d.department_id
	WHERE e.employee_id is NULL

7.列出所有没入部门的人员和没人入的部门

SELECT
	e.employee_id,
	e.last_name,
	d.department_name,
	d.department_id 
FROM
	employees e
	LEFT JOIN departments d ON e.department_id = d.department_id 
WHERE
	d.department_name IS NULL 

UNION ALL

SELECT
	e.employee_id,
	e.last_name,
	d.department_name,
	d.department_id 
FROM
	employees e
	RIGHT JOIN departments d ON e.department_id = d.department_id 
WHERE
	e.employee_id IS NULL 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在进行mysql关联查询时,可以采取以下几种方法来进行优化: 1. 使用正确的连接类型:根据查询需求选择合适的连接类型,如INNER JOIN、LEFT JOIN等,以减少不必要的数据集。 2. 优化WHERE子句:为关联字段创建索引,以提高查询效率。同时,尽量避免在WHERE子句中使用函数或达式,以充分利用索引。 3. 减少查询的字段:只选择需要的字段,避免查询不必要的数据,以减少查询的开销。 4. 考虑使用分布式查询:对于大型数据集,可以考虑将查询分解为多个小查询,并使用并行处理来提高查询性能。 5. 尽量避免子查询:子查询会增加查询的复杂度和开销,如果可能的话,可以尝试使用JOIN来替代子查询。 6. 优化连接顺序:根据的大小和关联条件的复杂度,调整连接的顺序,以减少中间结果集的大小。 7. 利用EXPLAIN分析查询:使用EXPLAIN命令来分析查询的执行计划,以找出潜在的性能问题,并进行相应的优化。 8. 分解复杂查询:对于复杂的查询语句,可以将其分解为多个简单的查询,以提高查询的效率。 9. 使用视图或存储过程:对于频繁使用的查询,可以考虑创建视图或存储过程,以减少查询的复杂度和开销。 综上所述,通过使用正确的连接类型、优化WHERE子句、为关联字段创建索引、减少查询的字段、考虑使用分布式查询、尽量避免子查询、优化连接顺序、利用EXPLAIN分析查询、分解复杂查询和使用视图或存储过程等方法,可以有效地优化mysql关联查询的性能。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* *2* *3* [mysql关联查询如何改进](https://blog.csdn.net/HongZeng_CSDN/article/details/130047902)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值