MySql学习4:多表查询

教程来源

黑马程序员 MySQL数据库入门到精通,从mysql安装到mysql高级、mysql优化全囊括

多表关系

各个表结构之间存在各种关联关系,基本上分为三种:一对多(多对一)、多对多、一对一

一对多(多对一)
例如:部门与员工的关系。一个部门对应多个员工、一个员工对应一个部门(不考虑一个员工对应多个部门的情况)

实现:在多的一方建立外键,指向一的一方的主键

多对多
例如:学生与课程的关系。一个学生可以选修多门课程,一门课程也可以供多个学生选择

实现:建立第三张中间表,中间表至少包含两个外键,分别关联两份主键
MySql学习4:多表查询_第1张图片
MySql学习4:多表查询_第2张图片
一对一
例如:用户与用户详情的关系。一对一关系多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率。

比如:提高查询性能,当一张表中数据过多时查询会变得缓慢;可以使数据库结构更清晰,每个表的结构更加简单

可以在任何一方加入外键,关联另一方的主键,并且设置外键为唯一的。
MySql学习4:多表查询_第3张图片

多表查询概述

指从多张表中查询数据。

笛卡尔积

MySql学习4:多表查询_第4张图片
笛卡尔积:指在数学中,两个集合A、B的所有组合情况。在多表查询时需要消除无效的笛卡尔积
MySql学习4:多表查询_第5张图片
分类

  • 连接查询

    • 内连接:相当于查询A、B交集的部分
    • 外连接:
      • 左外连接:查询左表所有数据,以及两张表交集部分数据
      • 右外连接:查询右表所有数据 ,以及两张表交集部分数据
    • 自连接:当前表与自身的连接查询,自连接必须使用表别名
  • 子查询

内连接

内连接查询的是两张表交集的部分

隐式内连接

select 字段 from 表1,2 where 条件

显示内连接

select 字段列表 from 表1 join 表2 on 连接条件

查询员工工号、姓名及所在部门的名称

// 隐式内连接
select emp.workno,emp.name,dept.dept_name  from emp,dept where emp.dept_id = dept.id;
// 显示外连接
select emp.workno,emp.name,dept.dept_name from emp join dept on emp.dept_id = dept.id;

MySql学习4:多表查询_第6张图片

外连接

左外连接

select 字段 from 表1 left join 表2 on 条件

查询emp表的所有数据,和对应的部门信息

select emp.*,dept.dept_name  from emp left join dept on emp.dept_id = dept.id;

MySql学习4:多表查询_第7张图片
这里与内连接的区别,假如有一个新员工刚入职还没有对应的部门,内连接是不会查询出该员工的信息,而左外连接会查询到该信息。

内连接是两边都要有;左外连接是左边都要有,右边可以不要有

右外连接

select 字段 from 表1 right join 表2 on 条件

查询dept的所有数据,和对应的员工表的信息

自连接

select 字段列表 from 表A join 表A 别名B  on 条件

自连接查询,可以是内连接查询,也可以是外连接查询。
例如,当表中的数据具有层级结构时,可以使用自连接来查询父子关系或者层级关系。比如,在员工表中查询员工的上级领导或者下属。

自连接可以帮助我们在同一表中进行比较和分析操作,解决一些复杂的查询需求。但是需要注意,在使用自连接时需要谨慎处理好连接条件,避免出现无限循环或者性能问题。

select emp.*,a.name  from emp join emp as a where emp.manager_id = a.id ;

MySql学习4:多表查询_第8张图片

联合查询

联合查询就是把多次查询的结果合并起来,形成一个新的查询结果集。比如,查询出薪资低于5000的员工和年龄大于60的员工。

关键字:union all union,后者是对前者的一个数据去重。

联合查询时多张表的列数必须保持一致、字段类型也需要保持一致。

select 字段列表 from a 条件
union 
select 字段列表 from b 条件

子查询

SQL中嵌套select语句,称为嵌套查询,又称子查询。

select * from t1 where column1 = (select column1 from t2)

子查询的外部语句可以是insertdeleteupdateselect中的任何一个

根据子查询的结果,可以分为:

  • 标量子查询,子查询结果是单个值
  • 列子查询,子查询的结果是一列
  • 行子查询,子查询的结果是一行
  • 表子查询,子查询的结果为多行多列

标量子查询

子查询返回的结果是单个值(数字、字符串、日期等),这种子查询称为标量子查询。

常用的操作符有:><!==

查询出研发中心的所有员工信息:
1)先查询出研发中心的部门id
2)根据部门id查询员工信息

select * from emp where dept_id = (select id from dept where dept_name = '研发中心')

列子查询

子查询返回的结果是一列(可以是多列),这种子查询称为列子查询
常用的操作符有:innot inandsomeall

查询交付中心和研发中心的所有员工信息
1)查询出交付中心和研发中心的部门id
2)根据部门id查询员工信息

select * from emp where dept_id  in (select id from dept where dept_name in ('交付中心','研发中心'))

行子查询

子查询返回的结果是一行(可以是多列),这种子查询称为行子查询
常用的操作符有:><!==

查询与秦一的性别相同的同部门员工信息
1)查询秦一的性别与部门id
2)根据性别和部门id查询员工信息

select * from emp where (sex ,dept_id) = (select sex ,dept_id  from emp where name = '秦一')

表子查询

子查询返回的结果是多行多列,这种子查询称为表子查询

常用操作符:in

查询与秦一、李二的性别和部门相同的员工信息

select * from emp where (sex ,dept_id) in (select sex ,dept_id  from emp where name = '秦一' or name = '李二')

查询入职日期是2023-06-12之后的员工信息,及其部门信息

select e.*,d.* from (select * from emp where entrydata > '2023-06-12') as e 
left join dept as d on e.dept_id = d.id

你可能感兴趣的:(MySQL,mysql,数据库)