MySQL多表查询 子查询效率(DQL语句)

这篇具有很好参考价值的文章主要介绍了MySQL多表查询 子查询效率(DQL语句)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

多表关系

项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构,由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种:

  • 一对多(多对一)
  • 多对多
  • 一对一

一对多

部门与员工的关系:一个部门对应多个员工,一个员工对应一个部门。

实现:在多的一方建立外键,指向一的一方的主键。
MySQL多表查询 子查询效率(DQL语句)

多对多

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

实现:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键。
MySQL多表查询 子查询效率(DQL语句)

一对一

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

实现:在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(UNIQUE)。
MySQL多表查询 子查询效率(DQL语句)

笛卡尔积

笛卡尔积:笛卡尔乘积是指在数学中,两个集合A集合 和 B集合的所有组合情况。
MySQL多表查询 子查询效率(DQL语句)

而在多表查询中,需要消除无效的笛卡尔积,只保留两张表关联部分的数据。
MySQL多表查询 子查询效率(DQL语句)

-- 设置过滤条件 Column 'id' in where clause is ambiguous
select * from emp,dept where id=5;
select * from emp,dept where emp.`dept_id` = dept.`id`;
-- 查询员工和部门的名字
select emp.`name`, dept.`name` from emp,dept where emp.`dept_id` = dept.`id`;

多表查询分类

  • 内连接:相当于查询A、B交集部分数据

  • 外连接:

    • 左外连接:查询左表所有数据,以及两张表交集部分数据
    • 右外连接:查询右表所有数据,以及两张表交集部分数据
  • 自连接:当前表与自身的连接查询,自连接必须使用表别名
    MySQL多表查询 子查询效率(DQL语句)

  • 子查询

表连接

内连接

内连接查询的是两张表交集部分的数据。(也就是绿色部分的数据)。

MySQL多表查询 子查询效率(DQL语句)

内连接的语法分为两种:隐式内连接、显式内连接。

  • select 字段名 from 左表, 右表 where 条件隐式内连接,看不到 join 关键字,条件使用 where 指定。
  • select 字段名 from 左表 [inner] join 右表 where 条件显式内连接,可以省略 inner。

总结:

  • 内连接的数据表不一定必须有同名字段,只要字段之间符合逻辑关系就可以。
  • 相同的数据表也可以做表连接。
  • 结果集也可以作为一张“表”来跟其他表连接。
-- 隐式内连接
select * from emp,dept where emp.`dept_id` = dept.`id`;

-- 确定表连接条件,员工表.dept_id = 部门表.id 的数据才是有效的
select * from emp e inner join dept d on e.`dept_id` = d.`id`;

-- 查询与SCOTT相同部门的员工都有谁
select e2.ename
from t_emp e1 join t_emp e2 on e1.deptno = e2.deptno 
where e1.ename = "SCOTT" and e2.ename != "SCOTT"

-- 查询月薪超过公司平均月薪的员工信息
select e.*
from t_emp e 
join (select avg(sal) avg from t_emp) t 
on e.sal >= t.avg

外连接

外连接与内连接的区别在于,除了符合条件的记录之外,结果集中还会保留不符合条件的记录。左外连接就是保留左表所有的记录,与右表做连接。如果右表有符合条件的记录就与左表连接。如果右表没有符合条件的记录,就用NULL与左表连接。右外连接也是如此。

内连接只保留符合条件的记录,所以查询条件写在ON子句和WHERE子句中的效果是相同的。但是外连接里,条件写在WHERE子句里,不合符条件的记录是会被过滤掉的,而不是保留下来。

  • select 字段名 from 左表 left [outer] join 右表 on 条件左外连接,outer 可以省略,用左边表的记录去匹配右边表的记录,如果符合条件的则显示;否则,显示 NULL。

左外连接相当于查询表1(左表)的所有数据,也包含表1和表2交集部分的数据。

  • select 字段名 from 左表 right [outer] join 右表 on 条件右外连接,outer 可以省略,用右边表的记录去匹配左边表的记录,如果符合条件的则显示;否则,显示 NULL

右外连接相当于查询表2(右表)的所有数据,也包含表1和表2交集部分的数据。

-- 在员工表中增加一个员工
insert into emp values (null, '沙僧','男',6666,'2013-12-05',null);
select * from emp;
-- 使用内连接查询
select * from dept inner join emp on dept.`id` = emp.`dept_id`;
-- 使用右外连接查询
select * from dept right join emp on dept.`id` = emp.`dept_id`;

自连接

自连接查询就是把一张表连接查询多次。可以是内连接查询,也可以是外连接查询。

  • select 字段列表 from 表A 别名A join 表A 别名B on 条件 ... ;:自连接查询

在自连接查询中,必须要为表起别名,要不然不清楚所指定的条件、返回的字段,到底是哪一张表的字段。

-- 查询员工 及其 所属领导的名字
select a.name , b.name from emp a , emp b where a.managerid = b.id;

--  查询所有员工 emp 及其领导的名字 emp , 如果员工没有领导, 也需要查询出来表结构: emp a , emp b
select a.name '员工', b.name '领导' from emp a left join emp b on a.managerid = b.id;

联合查询

union查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。

  • (查询语句) UNION (查询语句) UNION (查询语句) ...:UNION关键字可以将多个查询语句的结果集进行合并
  • 对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
  • union all 会将全部的数据直接合并在一起,union 会对合并之后的数据去重。
  • 如果多条查询语句查询出来的结果,字段数量不一致,会报错。
-- 将薪资低于 5000 的员工 , 和 年龄大于 50 岁的员工全部查询出来
-- 不去重
select * from emp where salary < 5000 
union all 
select * from emp where age > 50;

MySQL多表查询 子查询效率(DQL语句)

-- 去重
select * from emp where salary < 5000 
union 
select * from emp where age > 50;

MySQL多表查询 子查询效率(DQL语句)

子查询

子查询可以写在三个地方:WHERE子句、FROM子句、SELECT子句,但是只有FROM子句子查询是最可取的。

根据子查询结果不同,分为:

  • 标量子查询(子查询结果为单个值)
  • 列子查询(子查询结果为一列)
  • 行子查询(子查询结果为一行)
  • 表子查询(子查询结果为多行多列)

查询语句执行的时候要多次的依赖于子查询的结果,这类子查询被称作相关子查询,WHERE子查询和SELECT子查询都属于相关子查询。因为相关子查询要反复多次执行,所以应该避免使用。

EXISTS关键字

EXISTS关键字是把原来在子查询之外的条件判断,写到了子查询的里面。

  • select …… from 表名 where [not] exists ( 子查询 );

标量子查询(结果是一个值)

子查询结果只要是单行单列,肯定在 WHERE 后面作为条件,父查询使用:比较运算符,如:> 、<、<>、= 等。

  • select 查询字段 from 表 where 字段 = (子查询);
-- 1) 查询最高工资是多少
select max(salary) from emp;
-- 2) 根据最高工资到员工表查询到对应的员工信息
select * from emp where salary = (select max(salary) from emp);

-- 1) 查询平均工资是多少
select avg(salary) from emp;
-- 2) 到员工表查询小于平均的员工信息
select * from emp where salary < (select avg(salary) from emp);

列子查询(结果是多行单列)

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

常用的操作符:in、not in、any、some、all

操作符 描述
in 在指定的集合范围之内,多选一
not in 不在指定的集合范围之内
any 子查询返回列表中,有任意一个满足即可
some 与ANY等同,使用SOME的地方都可以使用ANY
all 子查询返回列表的所有值都必须满足
  • select 查询字段 from 表 where 字段 in (子查询);
-- 先查询大于 5000 的员工所在的部门 id
select dept_id from emp where salary > 5000;
-- 再查询在这些部门 id 中部门的名字 Subquery returns more than 1 row
select name from dept where id = (select dept_id from emp where salary > 5000);
select name from dept where id in (select dept_id from emp where salary > 5000);

-- 先查询开发部与财务部的 id
select id from dept where name in('开发部','财务部');
-- 再查询在这些部门 id 中有哪些员工
select * from emp where dept_id in (select id from dept where name in('开发部','财务部'));

-- 查询比 财务部 所有人工资都高的员工信息
-- 1.查询所有 财务部 人员工资
select salary from emp where dept_id = (select id from dept where name = '财务部');
-- 2.比 财务部 所有人工资都高的员工信息
select * from emp where salary > all ( select salary from emp where dept_id = (select id from dept where name = '财务部') );

-- 查询比研发部其中任意一人工资高的员工信息
-- 1.查询研发部所有人工资
select salary from emp where dept_id = (select id from dept where name = '研发部');
-- 2.比研发部其中任意一人工资高的员工信息
select * from emp where salary > any (select salary from emp where dept_id = (select id from dept where name = '研发部'));

行子查询(结果是一行多列)

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

常用的操作符:= 、<> 、IN 、NOT IN

-- 查询与 "张无忌" 的薪资及直属领导相同的员工信息
-- 1. 查询 "张无忌" 的薪资及直属领导
select salary, managerid from emp where name = '张无忌';
-- 2. 查询与 "张无忌" 的薪资及直属领导相同的员工信息 ;
select * from emp where (salary,managerid) = (select salary, managerid from emp where name = '张无忌');

表子查询(结果是多行多列)

子查询返回的结果是多行多列,这种子查询称为表子查询。子查询结果只要是多列,一般在 from 后面作为表。

  • select 查询字段 from (子查询) 表别名 where 条件;

子查询作为表需要取别名,否则这张表没有名称则无法访问表中的字段。

-- 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息
-- 1.  查询 "鹿杖客" , "宋远桥" 的职位和薪资
select job, salary from emp where name = '鹿杖客' or name = '宋远桥';
-- 2. 查询与 "鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息
select * from emp where (job,salary) in ( select job, salary from emp where name = '鹿杖客' or name = '宋远桥' );

-- 查询入职日期是 "2006-01-01" 之后的员工信息 , 及其部门信息
-- 1. 入职日期是 "2006-01-01" 之后的员工信息
select * from emp where entrydate > '2006-01-01';
-- 2. 查询这部分员工, 对应的部门信息;
select e.*, d.* from (select * from emp where entrydate > '2006-01-01') e left join dept d on e.dept_id = d.id ;

子查询效率问题

WHERE子查询

这种子查询最简单,最容易理解,但是却是效率很低的子查询。
MySQL多表查询 子查询效率(DQL语句)

用表连接替代WHERE子查询:

表连接的优点是子查询只执行一次,查询效率特别高
MySQL多表查询 子查询效率(DQL语句)

FROM子查询

这种子查询只会执行一次,所以查询效率很高。
MySQL多表查询 子查询效率(DQL语句)

SELECT子查询

这种子查询每输出一条记录的时候都要执行一次,查询效率很低。
MySQL多表查询 子查询效率(DQL语句)文章来源地址https://www.toymoban.com/news/detail-404431.html

到了这里,关于MySQL多表查询 子查询效率(DQL语句)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SQL语句详解四-DQL(数据查询语言-约束)

    概述:对表中的数据进行限定,保证数据的正确性,有效性和完整性。 约束分类 约束 约束意思 primary key 主键约束 not null 非空约束 unique 唯一约束 foreign key 外键约束 例子:sname varchar(40) not null, – 代表 sname 这个字段不能为 NULL 非空约束 概述:NOT NULL ,某一列的值不能

    2024年01月16日
    浏览(49)
  • 【MySQL 系列】MySQL 语句篇_DQL 语句

    DQL(Data Query Language),即数据查询语言,用来查询数据记录。DQL 基本结构由 SELECT FROM 、 WHERE 、 JOIN 等子句构成。 DQL 语句并不会改变数据库,而是让数据库将查询结果发送结果集给客户端,返回的结果是一张虚拟表。 1、MySQL 中的 DQL 语句 1.1、数据查询语言–DQL DQL(Data Q

    2024年03月14日
    浏览(58)
  • 数据库 SQL高级查询语句:聚合查询,多表查询,连接查询

    创建Students和Courses表 直接查询 设置别名查询 设置条件查询 使用COUNT(*) 和 COUNT(StudentID)是一样的效果,因为StudentID是主键,每行记录的主键都不同。另外我们在聚合查询中还是能使用WHERE子句的,比如我们要 查找年龄大于20岁的学生数量 ,可使用以下SQL语句: 函数 说明 SUM

    2024年02月09日
    浏览(126)
  • SQL语句 - 多表查询使用详细介绍

    例如我们有一张员工表和部门表, 员工表有6条数据, 部门表表有4条数据 : 使用多表查询, 查询员工表和部门表两张表 : 此时查询到的结果会有24条数据, 为什么会这样呢 ? 笛卡尔积:有A, B两个集合, 取A, B集合所有组合情况(4*6=24); 我们多表查询, 更多的是消除这些无效的数据 例

    2024年01月16日
    浏览(50)
  • SQL两表/多表关联查询--JOIN语句

    一、基础概念 SQL中的关联是通过JOIN实现的,JOIN有几种类型,包括INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN等。 二、INNER JOIN详解 INNER JOIN是最常用的关联方式之一,它 返回 两个表中共同存在的数据行 。 其语法格式如下: 下面是一个实际的例子: 以上代码可以

    2024年01月18日
    浏览(56)
  • 【MySQL基础|第三篇】--- 详谈SQL中的DQL语句

    个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【MySQL学习专栏】🎈 本专栏旨在分享学习MySQL的一点学习心得,欢迎大家在评论区讨论💌 DQL(Data Query Language) 是 数据库查询语言 ,用来查询数据库表中的记录。查询

    2024年02月07日
    浏览(44)
  • 【MySQL 数据库】1、MySQL 的 DDL、DML、DQL 语句

    🎄 (1) MySQL 基础篇(初级工程师) ① MySQL 基础概念 ② SQL 语句 ③ 函数 ④ 约束 ⑤ 多表查询 ⑥ 事务 🎄 (2) MySQL 进阶篇(中级工程师) ① 存储引擎 ② 索引 ③ SQL 优化 ④ 视图、存储过程、触发器 ⑤ 锁 ⑥ InnoDB 核心 ⑦ MySQL 管理 🎄 (3) 运维篇(高级工程师) ① 日志 ② 主

    2024年02月05日
    浏览(47)
  • MySQL之DQL——查询语言

    前言         今天给大家带来关于数据库查询相关操作,希望各位看官能看个愉快   目录 一、基本概念 1.1、基本概念 1.2、SQL语言的分类 1.3、数据库的存储特点 二、MySQL   2.1、 MySQL服务的登录和退出   2.2、 MySQL服务的启动和停止 2.3、MySQL常见数据指令 2.4、MySQL语法规范

    2023年04月24日
    浏览(42)
  • 十、MySQL(DQL)条件查询

    :表示且 and:表示且 between……and……:between之后为最小值,and之后为最大值 or:表示或 in(参数1,参数2,参数3……):符合参数即可输出 _下划线:每一个下划线,代表一个占位 %数字:表示从末尾开始匹配,符合即可输出

    2024年02月10日
    浏览(41)
  • MySQL_约束、多表关系

    概念:就是用来作用表中字段的规则,用于限制存储在表中的数据。 目的:保证数据库中数据的正确性,有效性和完整性。 约束演示 外键约束 概念:用户建立两张表之间的联系的,为了保证数据的一致性和完整性的。 注意上面创建的时候没有使用外键真正的来管理数据,

    2024年02月13日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包