【MySQL】解锁表的 N 种牵手方式:SQL 连接与子查询漫游(复合查询)

一、多表查询

显示雇员名、雇员工资以及所在部门的名字:

为了得出结果,我们必须让这两张表合并成一张表:

得到的一张非常大的表,这个表是由 emp 表的第一行和 dept 表的第一行、第二行等进行组合而来,以此类推,emp 表的第二行和 dept 的表的第一行、第二行等进行组合等等,最终得到这张表;这个结果称为笛卡尔积;

为了让员工的 emp 的部门编号和 dept 的部门编号进行适配,最终达成部门一致:

最后:显示员工名字、工资、部门:

显示部门号为10的部门名,员工名和工资:

显示各个员工的姓名,工资,及工资级别:

二、自连接

对同一张表进行笛卡尔积的操作称为自连接:

显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号--empno):

1)使用子查询:

2)自连接:

三、单行子查询

显示SMITH同一部门的员工:

三、多行子查询

查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己:

显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号:

显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工):

四、多列子查询

查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人:

mysql> select * from emp where (deptno,job) = (select deptno,job from emp where ename='SMITH');

+--------+-------+-------+------+---------------------+---------+------+--------+

| empno | ename | job | mgr | hiredate | sal | comm | deptno |

+--------+-------+-------+------+---------------------+---------+------+--------+

| 007369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800.00 | NULL | 20 |

| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |

+--------+-------+-------+------+---------------------+---------+------+--------+

2 rows in set (0.00 sec)

mysql> select * from emp where (deptno,job) = (select deptno,job from emp where ename='SMITH') and ename != 'SMITH';

+--------+-------+-------+------+---------------------+---------+------+--------+

| empno | ename | job | mgr | hiredate | sal | comm | deptno |

+--------+-------+-------+------+---------------------+---------+------+--------+

| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |

+--------+-------+-------+------+---------------------+---------+------+--------+

1 row in set (0.00 sec)

mysql> select * from emp where (deptno,job) in (select deptno,job from emp where ename='SMITH') and ename != 'SMITH';

+--------+-------+-------+------+---------------------+---------+------+--------+

| empno | ename | job | mgr | hiredate | sal | comm | deptno |

+--------+-------+-------+------+---------------------+---------+------+--------+

| 007876 | ADAMS | CLERK | 7788 | 1987-05-23 00:00:00 | 1100.00 | NULL | 20 |

+--------+-------+-------+------+---------------------+---------+------+--------+

1 row in set (0.01 sec)

五、在 from 子句中使用子查询

之前我们都是在 where 右侧使用子查询,现在我们来使用在 from 中使用子查询:

显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资:

mysql> select * from emp,(select deptno,avg(sal) myavg from emp group by deptno) tmp where emp.deptno=tmp.deptno and emp.sal>tmp.myavg;

·查找每个部门工资最高的人的姓名、工资、部门、最高工资:

mysql> select ename,sal,t1.deptno,mymax from emp t1,(select deptno,max(sal) mymax from emp group by deptno) t2 where t1.deptno=t2.deptno and t1.sal=t2.mymax;

显示每个部门的信息(部门名,编号,地址)和人员数量:

mysql> select t1.dname,t1.loc,t2.dept_num,t1.deptno from dept t1,(select deptno,count(*) dept_num from emp group by deptno) t2 where t1.deptno=t2.deptno;

解决多表问题的本质:想办法将多表转换成单表,所以在 MySQL 中,所有的 select 的问题全部都可以转成单表问题;

六、合并查询

在实际应用中,为了合并多个select的执行结果,可以使用集合操作符union,union all;

union:该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。

将工资大于2500或职位是MANAGER的人找出来:

union all:该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

七、内连接

八、外连接

1)左外连接

查询所有学生的成绩,如果这个学生没有成绩,也要将学生的个人信息显示出来:

2)右外连接

相关推荐
ss2734 小时前
为什么PostgreSQL适合AI场景?
数据库·人工智能·postgresql
瑞克-桑切斯4 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
z06.5 小时前
MySQL索引
数据库·mysql
考虑考虑5 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
云祺vinchin5 小时前
中小企业备份软件选型从恢复需求到总体成本评估
数据库·数据备份·中小企业备份·容灾备份软件
Zenova EdgeOS5 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
KKKlucifer5 小时前
国内数据安全服务的产品智能化转型:大模型赋能下的技术能力重构分析
大数据·数据库·重构
字节跳动开源6 小时前
OpenViking 上线原生 3D 内容理解模型
数据库·开源
CCIE-Yasuo8 小时前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
这个DBA有点耶8 小时前
内核级AI与多模融合:AI数据库在海外场景的落地要点
数据库·人工智能·架构