找回密码
 立即注册
快捷导航

[数据库] 多表查询

[复制链接]
镖师 2023-7-11 19:22:09 | 显示全部楼层
本帖最后由 镖师 于 2023-7-11 21:10 编辑

多表查询,也称为关联查询,指两个或更多个表一起完成查询操作。
多表查询9976 作者:镖师 帖子ID:468

笛卡尔积 (交叉连接,CROSS JOIN)
SELECT last_name,department_name FROM employees, departments;
SELECT last_name,department_name FROM employees CROSS JOIN departments;
SELECT last_name,department_name FROM employees INNER JOIN departments;
SELECT last_name,department_name FROM employees JOIN departments
多表查询1959 作者:镖师 帖子ID:468
出现笛卡尔积的原因是:多表查询时没有连接条件或连接条件无效

#案例:查询员工的姓名及其部门名称
SELECT employees.last_name, departments.department_name FROM employees, departments
WHERE employees.department_id = departments.department_id;
注意:如果某个员工没有部门(员工的部门id为NULL),则不会查询这个员工出来;

表别名
SELECT emp.last_name, dep.department_name FROM employees emp, departments dep
WHERE emp.department_id = dep.department_id;
注意:表起了别名,就不能再select和where中再用表名作为前缀了;

多表查询的分类
角度1(连接条件):等值连接(上面的就是等值) vs 非等值连接
角度2(自我引用):自连接 vs 非自连接
角度3:内连接 vs 外连接

非等值连接
多表查询5678 作者:镖师 帖子ID:468


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;

非自连接
不同表之间的关联查询,上面写的都是非自连接

自连接
自己表连接自己表
多表查询4582 作者:镖师 帖子ID:468
查询 员工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



内连接 和 外连接
上面写的sql语句,都是内连接
内连接:将满足连接条件的数据查出来了,而没满足条件的其他数据都没有要,这种就叫内连接
比如:员工表和部门表,假如员工表的某个员工没有设置部门id(NULL),那么内连接查询出来是不包含这个员工的;
select last_name, department_name from employees e
inner join departments d on e.department_id = d.department_id;    -- inner可以省略
多表查询5143 作者:镖师 帖子ID:468

外连接
两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)表中不满足条件的行 ,这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL)。
如果是左外连接,则连接条件中左边的表也称为 主表 ,右边的表称为 从表 。
如果是右外连接,则连接条件中右边的表也称为 主表 ,左边的表称为 从表 。

题目:查询所有的员工的last_name,department_name的信息
select last_name, department_name from employees e
left outer join departments d on e.department_id = d.department_id;    -- outer 可以省略
多表查询5134 作者:镖师 帖子ID:468



UNION [ALL]
两个表合并成一个,两个表的列数和数据类型必须一致且相互对应;
UNION:返回两个查询结果集的并集,去除重复记录;
UNION ALL:符返回两个查询的结果集的并集。对于两个结果集的重复部分,不去重。

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



多表查询513 作者:镖师 帖子ID:468

#中图:内连接 A∩B
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 LEFT JOIN departments d
ON e.`department_id` = d.`department_id`;

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

#左中图:A - A∩B
SELECT employee_id,last_name,department_name FROM employees e LEFT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE d.`department_id` IS NULL

#右中图:B-A∩B
SELECT employee_id,last_name,department_name FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL

#左下图:满外连接
# 左中图 + 右上图 A∪B
SELECT employee_id,last_name,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,last_name,department_name FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`;

#右下图
#左中图 + 右中图 A ∪B- A∩B 或者 (A - A∩B) ∪ (B - A∩B)
SELECT employee_id,last_name,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,last_name,department_name
FROM employees e RIGHT JOIN departments d
ON e.`department_id` = d.`department_id`
WHERE e.`department_id` IS NULL





我们要 控制连接表的数量 。多表连接就相当于嵌套 for 循环一样,非常消耗资源,会让 SQL 查询性能下降得很严重,因此不要连接不必要的表。在许多 DBMS 中,也都会有最大连接表的限制。
【强制】超过三个表禁止 join。需要 join 的字段,数据类型保持绝对一致;多表关联查询时, 保证被关联的字段需要有索引。
说明:即使双表 join 也要注意表索引、SQL 性能。
来源:阿里巴巴《Java开发手册》
回复

使用道具 举报

主题

0

回帖

440

积分

已臻大成

 楼主| 镖师 2023-7-11 21:47:22 | 显示全部楼层
# 7.查询哪些部门没有员工

# 8. 查询哪个城市没有部门   
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼
温馨提示

关于 注册码 问题

      由于近期经常大量注册机器人注册发送大量广告,本站开启免费入群领取注册码注册网站账号,注册码在群公告上贴着...

关于 注册码 问题

      由于近期经常大量注册机器人注册发送大量广告,本站开启免费入群领取注册码注册网站账号,注册码在群公告上贴着...

Archiver|手机版|小黑屋|DLSite

GMT+8, 2024-11-23 00:35

Powered by Discuz! X3.5 and PHP8

快速回复 返回顶部 返回列表