MySql学习4:多表查询

教程来源

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

多表关系

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

一对多(多对一)

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

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

多对多

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

实现:建立第三张中间表,中间表至少包含两个外键,分别关联两份主键


一对一

例如:用户与用户详情的关系。一对一关系多用于单表拆分,将一张表的基础字段放在一张表中,其他详情字段放在另一张表中,以提升操作效率。

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

可以在任何一方加入外键,关联另一方的主键,并且设置外键为唯一的。

多表查询概述

指从多张表中查询数据。

笛卡尔积

笛卡尔积:指在数学中,两个集合A、B的所有组合情况。在多表查询时需要消除无效的笛卡尔积

分类

  • 连接查询

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

内连接

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

隐式内连接

dart 复制代码
select 字段 from 表1,表2 where 条件

显示内连接

dart 复制代码
select 字段列表 from 表1 join 表2 on 连接条件

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

dart 复制代码
// 隐式内连接
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;

外连接

左外连接

dart 复制代码
select 字段 from 表1 left join 表2 on 条件

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

dart 复制代码
select emp.*,dept.dept_name  from emp left join dept on emp.dept_id = dept.id;

这里与内连接的区别,假如有一个新员工刚入职还没有对应的部门,内连接是不会查询出该员工的信息,而左外连接会查询到该信息。

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

右外连接

dart 复制代码
select 字段 from 表1 right join 表2 on 条件

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

自连接

dart 复制代码
select 字段列表 from 表A join 表A 别名B  on 条件

自连接查询,可以是内连接查询,也可以是外连接查询。

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

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

dart 复制代码
select emp.*,a.name  from emp join emp as a where emp.manager_id = a.id ;

联合查询

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

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

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

dart 复制代码
select 字段列表 from a 条件
union 
select 字段列表 from b 条件

子查询

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

dart 复制代码
select * from t1 where column1 = (select column1 from t2)

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

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

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

标量子查询

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

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

查询出研发中心的所有员工信息:

1)先查询出研发中心的部门id

2)根据部门id查询员工信息

dart 复制代码
select * from emp where dept_id = (select id from dept where dept_name = '研发中心')

列子查询

子查询返回的结果是一列(可以是多列),这种子查询称为列子查询

常用的操作符有:innot inandsomeall

查询交付中心和研发中心的所有员工信息

1)查询出交付中心和研发中心的部门id

2)根据部门id查询员工信息

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

行子查询

子查询返回的结果是一行(可以是多列),这种子查询称为行子查询

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

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

1)查询秦一的性别与部门id

2)根据性别和部门id查询员工信息

dart 复制代码
select * from emp where (sex ,dept_id) = (select sex ,dept_id  from emp where name = '秦一')

表子查询

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

常用操作符:in

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

dart 复制代码
select * from emp where (sex ,dept_id) in (select sex ,dept_id  from emp where name = '秦一' or name = '李二')

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

dart 复制代码
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
CodeAmaz2 分钟前
MySQL 事务的实现原理详解
数据库·mysql·事务·隔离性
♡喜欢做梦3 分钟前
MyBatis操作数据库(进阶):动态SQL
java·数据库·sql·java-ee·mybatis
copyer_xyf4 分钟前
SQL 语法速查手册:前端开发者的学习笔记
前端·数据库·sql
承缘丶5 分钟前
Excel字段清单转各类数据库建表语句的工具(开箱即用)
数据库·excel·excel转数据库建表语句
风123456789~2 小时前
【OceanBase专栏】脚本调用OB过程实验
数据库·oceanbase
n***s9096 小时前
【MySQL基础篇】概述及SQL指令:DDL及DML
sql·mysql·oracle
爬山算法6 小时前
Redis(158)Redis的主从同步问题如何解决?
数据库·redis·缓存
2501_941148159 小时前
多语言微服务架构与边缘计算技术实践:Python、Java、C++、Go深度解析
数据库
计算机毕设小月哥10 小时前
【Hadoop+Spark+python毕设】智能制造生产效能分析与可视化系统、计算机毕业设计、包括数据爬取、Spark、数据分析、数据可视化、Hadoop
后端·python·mysql