首页 > 数据库 >Mysql操作多表查询的方法

Mysql操作多表查询的方法

时间:2023-04-19 16:32:52浏览次数:42  
标签:多表 表中 查询 emp Mysql deptno 连接 select

多表查询是指在关系型数据库中,通过同时查询多个数据表来检索相关数据的操作。这种查询方式通常用于需要在多个数据表中搜索和比较数据的情况,以获取更完整和准确的结果。

在多表查询中,使用联接(join)操作将多个表连接在一起,并使用条件语句来指定要检索的数据。联接操作可以使用不同的方式进行,包括内部联接、外部联接、左联接、右联接等,这些方式可以根据查询需求选择不同的联接方式。

多表查询可以提高查询效率,避免重复的数据输入,并且可以根据需要获取更详细的查询结果。不过,在进行多表查询时,需要注意数据库表之间的关系、数据类型和查询条件等因素,以确保查询结果的准确性和完整性。

举个例子,如果我们需要查询一篇文章的作者姓名和发表时间,那么这个信息通常会被保存在不同的两个表中,一张表存储文章的信息,包括文章标题、内容等;另一张表存储作者的信息,包括姓名、ID等。在这种情况下,如果只查询文章表,我们只能获取文章的基本信息,无法获得作者的信息;但如果使用多表查询,我们就可以将两个表联接起来,获取文章的作者信息,从而得到更全面和详细的查询结果。

多表查询基本写法

-- 从两张表中查询数据
select * from A, B;

-- 从两张表中查询数据
select * from A join B;

TIPS:

其实,连接两张表进行查询,标准SQL采用的是join的语法。上述的select * from A, B;的写法,其实只是在MySQL中的“方言”,只在MySQL中生效,在其他的DBMS中就不一定能使用了。

select * from A, B; 其实是等价于 select * from A inner join B; 的。那么什么是inner join呢?后面会讲。

笛卡尔积

在做连接查询的时候,一张表中的每一行数据都会和另一张表中的每一行数据进行关联,形成笛卡尔积。

假如A表中有m行数据,B表中有n行数据,连接查询之后的结果就是m*n行数据,其中有太多的数据是我们不需要的了。

Mysql操作多表查询的方法_数据

image-20220109012327595

连接查询条件限制

通过上图,我们知道了在两张表进行连接查询的时候,会出现大量的无效的数据。因此,我们就需要通过一些操作,去除连接查询之后的无用的数据,只得到我们需要的数据!而这个过程是可以通过条件的限制来实现的:

  1. MySQL的查询方言
-- 用where进行条件的过滤,得到满足条件的所有的数据。
select * from A, B where A.empno = B.mgr;
  1. 标准SQL的语法
-- 用on的方式,进行连接查询的多余数据过滤
select * from A join B on A.empno = B.mgr;

连接查询分类

将两张表连接在一起查询的时候,通常情况下我们需要进行一定的条件限制,来达到去除查询结果笛卡尔积中多余的数据,保留我们需要的数据的目的。通常情况下,进行连接查询的多张表之间是有一定的逻辑关联的,具体表现为有一个相同的字段,在两张表中都会出现。因此,我们在进行连接查询的时候就会使用这个字段的值进行数据的过滤。

那么,连接查询就会出现这样的几种情况:

  • A表中,通过关联的字段,可以在B表中查询到数据。
  • A表中,通过关联的字段,无法在B表中查询到数据。
  • B表中,通过关联的字段,无法的A表中查询到数据。

此时,根据所需的不同结果,可以将连接查询分为两类: 内连接、外连接

Mysql操作多表查询的方法_连接查询_02

image-20220109113112570

内连接

内连接,使用inner join来表示,在进行查询的时候,inner是可以省略的,因此通常情况下直接写join就是内连接。

所谓内连接,以左表为驱动表,右表为从动表。查询结果中保留A表的数据通过连接的字段,在B表中能够查询到的数据。

-- 查询员工的编号、职位、入职时间、部门编号、部门名称
select empno, job, hiredate, deptno, dname from emp join dept on emp.deptno = dept.deptno;

-- 查询LOCATION在NEW YORK的员工数量
select count(*) from emp join dept on emp.deptno = dept.deptno where loc = 'NEW YORK';

外连接

外连接,使用outer join来表示,但是外连接还有更加明细的分类: 左外连接和右外连接。

  • 左外连接: 以左表为驱动表,右表为从动表,查询结果中保留A表的数据通过连接的字段,在B表中能够查询到的数据。如果通过这个连接字段无法在B表中查询到数据,则B表与之关联的就是null数据。
  • 右外连接: 以右表为驱动表,左表为从动表,查询结果中保留B表的数据通过连接的字段,在A表中能够查询到的数据。如果通过这个连接字段无法在A表中查询到数据,则A表与之关联的就是null数据。

总结来说

左外连接查询结果: 包含左表中的所有数据,右表与之关联的数据,如果在右表没有与之关联的数据,则用null填充。

右外连接查询结果: 包含右表中的所有数据,左表与之关联的数据,如果在左表没有与之关联的数据,则用null填充。

语法: 左外连接使用 left outer join来表示,右外连接使用 right outer join来表示。

而outer是可以省略不写的,也就是: 左外连接: left join,右外连接: right join

-- 查询所有的部门的人数
select deptno, dname, count(empno) from dept left join emp on dept.deptno = emp.deptno;

全连接

全连接,又叫全外连接。全连接的意义是保留两张表中的所有的数据。如果在另外一张表中没有与之连接的数据,使用null进行填充。也就是说,其实全连接就是将左外连接和右外连接的查询结果合并到一起并去除重复的数据。

MySQL不支持全连接!

虽然MySQL不支持全连接,但是可以使用其他的方式来间接实现:

将左外连接和右外连接的查询结果,使用union合并到一起即可。

自然连接

我们在进行连接查询的时候,通常会在需要连接的两张表中找到字段关联在一起,而绝大多数情况下我们所需要进行的是等值连接。在进行数据库和表的设计的时候,这样用来联系多张表之间的关系的字段,一般情况下命名是相同的。

所谓“自然连接“指的就是找到需要进行连接查询的两张表中名字相同、类型也相同的字段,自动的使用这个字段作为连接的字段。如果不存在这样的名字相同的字段,会有错误。

select * from emp natural join dept;
select * from emp natural right join dept;

子查询

子查询简介

有的时候,当一个查询语句A所需要的数据,不是直观在表中体现,而是由另外一个查询语句B查询出来的结果,那么查询语句A就是主查询语句,查询语句B就是子查询语句。这种查询我们称之为高级关联查询,也叫做子查询。

子查询语句的返回数据形式:

- 返回单行单列	=> 可以被视为一个数值来使用
- 返回多行单列	=> 可以被视为一个集合来使用
- 返回单行多列	=> 可以被视为一个虚拟表使用
- 返回多行多列	=> 可以被视为一个虚拟表使用

子查询语句的位置可以在以下几个子句中:

- 在where子句中:	子查询的结果可用作条件筛选时使用的值。
- 在from子句中:		子查询的结果可充当一张表或视图,需要使用表别名。
- 在having子句中:	子查询的结果可用作分组查询再次条件过滤时使用的值
- 在select子句中:	子查询的结果可充当一个字段。仅限子查询返回单行单列的情况。

在where子句中

# 需求:查询工资大于员工编号为7369这个员工的所有员工信息。
# 解析:
# 第一步:目的是查询工资大于某一个数num的所有员工信息
#     select * from emp where sal>num
# 第二步:num的值7369员工的工资
#     select sal from emp where empno = 7369;
# 第三步:将主查询中的代词使用子查询语句替换
select * from emp where sal>(select sal from emp where empno = 7369);

# 需求:查询工资大于10号部门的平均工资的所有员工信息
select * from emp where sal>(select avg(ifnull(sal,0)) from emp where deptno=10);

# 需求:查询工资大于10号部门的平均工资的非10号部门的员工信息。
select * from emp where sal>(select avg(ifnull(sal,0)) from emp where deptno=10) and deptno<>10;

# 需求:查询与7369同部门的同事信息。
select * from emp where deptno=(select deptno from emp where empno=7369) and empno<>7369;

在from子句中

# 需求:查询员工的姓名,工资,及其部门的平均工资。
# 解析:
# 第一步:先查询每个部门的平均工资
# select deptno,avg(ifnull(sal,0)) from emp group by deptno;
# 第二步:将上一个查询语句的返回结果当成一张表,与员工表进行关联查询
select A.ename, A.sal, B.avg_sal
from emp A join (select deptno,avg(ifnull(sal,0)) avg_sal from emp group by deptno) B on A.deptno = B.deptno

在having子句中

# 需求:查询平均工资大于30号部门的平均工资的部门号,和平均工资
select deptno,avg(ifnull(sal,0)) from emp group by deptno having avg(ifnull(sal,0))>
(select avg(ifnull(sal,0)) from emp where deptno=30);

在select子句中

# 查询每个员工的信息及其部门的平均工资,工资之和,部门人数
select A.empno,A.ename,A.sal,
(select avg(ifnull(sal,0)) from emp B where B.deptno=A.deptno) avg_sal,
(select sum(sal) from emp C where C.deptno=A.deptno) sum_sal,
(select count(*) from emp D where D.deptno=A.deptno) count_
from emp A;

SQL完整的执行顺序

select distinct..from t1 [inner|left|right] join t2 on 条件 
where...group by...having...order by...limit

1. from t1
2. on 条件
3. [inner|left|right] join t2
4. where...
5. group by...
6. having...
7. select...
8. distinct...
9. order by...
10. limit....

合并查询结果集

合并查询结果集概述

合并结果集,就是将两次或者多次的查询结果,合并到一起,存入一张查询结果虚拟表中。

进行结果集合并的多张表,要求字段的数量是完全相同的。

A查询的结果有5个字段,B查询的结果有5个字段。此时是可以合并到一起的。

A查询的结果有5个字段,B查询的结果有3个字段。此时是无法合并到一起的。

合并查询结果集语法

  • union: 对两次的查询结果进行合并,对最终的合并结果会进行去重的处理。
  • union all : 对两次的查询结果的直接合并,没有进行去重的处理。

标签:多表,表中,查询,emp,Mysql,deptno,连接,select
From: https://blog.51cto.com/u_15739596/6206698

相关文章

  • 普罗米修斯MySQL监控
    1.下载MySQL的exporter下载地址:https://prometheus.io/download/ 2.上传到需要监控的MySQL的机器上进行解压 解压安装tar-xzvfmysqld_exporter-0.14.0.linux-amd64.tar.gz 为了后续使用方便将名称修改为:mysqld_exporterexportDATA_SOURCE_NAME='root:123456......
  • 从申请到调用:全国快递物流查询 API 使用教程
    引言面对越来越多的快递需求和快递公司的日益增多,手动查询快递状态的工作变得愈发繁琐。此时,一个全国快递物流查询API的出现能够极大地提高查询的效率和准确性,解决人工查询的问题,为用户提供更加便捷的服务体验。全国快递物流查询API可以通过接口自动查询快递状态并返回相应信......
  • MySQL 查看数据库表容量大小
    1.查看所有数据库容量大小selecttable_schemaas'数据库',sum(table_rows)as'记录数',sum(truncate(data_length/1024/1024,2))as'数据容量(MB)',sum(truncate(index_length/1024/1024,2))as'索引容量(MB)'frominformation_schema.t......
  • MySQL 级联查询所有父级
    表结构:idnamecodeparent_code1老板A 2总经理BA3项目总监CB4开发工程师DC      查询D开发工程师的所有上级:SELECT`name`,@`code`ASc_ids,(SELECT@`code`:=parent_codeFROMdepartWHERE`code`=@`code`)ASp_id......
  • 自定义Mybatis-plus插件(限制最大查询数量)
    自定义Mybatis-plus插件(限制最大查询数量)需求背景​ 一次查询如果结果返回太多(1万或更多),往往会导致系统性能下降,有时更会内存不足,影响系统稳定性,故需要做限制。解决思路1.经分析最后决定,应限制一次查询返回的最大结果数量不应该超出1万,对于一次返回结果大于限制的时候应该......
  • 组织树查询-Jvava实现(递归)
    1.首先查询出组织机构就是一个简单的查询List<Dept>deptList=mapper.getDeptList();Map<Long,OrgNode>nodeMap=newHashMap<>();List<Long>rootIds=newArrayList<>();for(Deptdept:deptList){Longd......
  • Mysql数据库的安装教程
    (Mysql数据库的安装教程)一、Mysql数据库介绍MySQL是一个关系型数据库管理系统,由瑞典MySQLAB公司开发,属于Oracle旗下产品。MySQL是最流行的关系型数据库管理系统之一,在WEB应用方面,MySQL是最好的RDBMS(RelationalDatabaseManagementSystem,关系数据库管理系统)应用软......
  • 6.1.4 MySQL缓存策略
    LinuxC/C++服务器MySQL缓存策略大部分场景下MySQL的读要远远大于写的需求的,急需要解决的问题是提升读的性能......
  • MYSQL索引失效场景及其原理
    MySQL索引失效是指查询时不能有效利用索引,从而导致查询性能下降的现象。以下是一些常见的MySQL索引失效场景及原理:使用函数或表达式:在WHERE子句中对索引列使用函数或表达式会导致索引失效。因为MySQL无法预先计算表达式的结果,所以无法使用索引进行查找。例:SELECT*FROMusersWH......
  • MySQL事务实现原理
    事务是什么?首先思考一个问题,事务是什么?以下是事务的相关解释MySQL中的事务是一种用于确保数据库操作的完整性和一致性的机制。事务处理具有以下四个基本特性,通常被称为ACID特性:原子性(Atomicity):原子性是指事务中的所有操作要么全部完成,要么全部不完成。事务中的操作不可分割,如果......