MYSQL之复杂查询_表链接

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: day2复杂查询_表链接

一、 分组

1、简单分组

  • 概念:一般配合组函数一起使用,不再将一张表作为一组数据,而将某列相同的数据划分为小组,对每个小组进行处理。
  • 9645a03f139f24d939cddf2760436a74[0].png

语法:

select...分组字段|组函数 
from... 
where... 
group by 分组字段 
order by ....


例:按照公司部门分组:

select department_id 
from employees 
group by department_id;


例:查询公司每个部门的最高工资

-- step 1: 按照部门分组 
select department_id 
from employees 
group by department_id; 
-- step 2:使用组函数找到最高工资 
select department_id , max(salary) 
from employees 
group by department_id;


2.png

注意:如果select语句后有未分组的列,只返回第一行数据,不会进行分组。不要出现未分组的字段

3.png

例:
select job_id , avg(salary) 
from employees; -- 100 6461 
更正:
select job_id, avg(salary) 
from employees
 group by job_id; -- OK


4.png


查询各个等级工资的人数

select salary,count(department_id) 人数 from employees
group by salary;
order by salary desc;

5.png

2、过滤后分组

  • 作用:在分组前使用where先过滤掉一部分数据再分组
  • 例:查询各个部门工资大于5000的员工数量
-- step1:按照部门进行分组 
select department_id 
from employees 
group by department_id; 
-- step2:统计员工数量 
select department_id , count(*) 
from employees 
group by department_id; 
-- step3:加入过滤条件 
select department_id , count(*)
 from employees 
 where  salary>5000
 group by department_id;


3、分组后过滤(having)

  • 作用:用于分组后的数据过滤,可以使用组函数。
  • 语法:
select... 
from.. 
where... 
group by... 
having.. 
order by...


例:查询部门平均工资高于6000的部门id、人数、平均工资


-- step 1 : 按照部门进行分组
 select department_id 
 from employees 
 group by department_id; 
 -- step 2:统计每个部门的人数与平均工资
  select department_id ,count(employee_id), avg(salary) 
  from employees 
  group by department_id;
   -- step 3:having过滤 平均工资
select department_id ,count(employee_id),avg(salary) 
from employees 
group by department_id 
having avg(salary)>6000;


where与having的区别:

1. where在group by之前执行,having在group by之后执行 
2. where以每个数据为单位进行过滤,
   having以每组数据为单位进行过滤,支持组函数


4、分页查询(limit)

  • 作用:limit关键字用来限制查询结果的条目数,通常用于分页查询。
  • 语法:
//sql语句中的最后一行语句 
limit offset,rows; 
-- offset:表示查询条目的起始下标, 
-- rows:表示最多显示多少条

例:获取前10行

select * from employees limit 0,10;


例:获取11行~20行

select * from employees limit 10,10;


当offset为0时,可以省略

例:

select * from employees limit 10;


二、SQL语句中关键字的执行顺序

  • select … from …where…group by…having…order by…
  • image.png


三、子查询

  • 作用:当一个查询SQL的条件需要使用另外一个查询SQL的结果时,需要在一个SQL语句中嵌套另外一个SQL语句。

1、单列单值子查询

  • 概念:子查询结果只有一个值时,可以利用该值进行二次查询

    例:查询比Nancy工资高的员工信息

-- step 1 :查询Nancy的工资 
select salary
 from employees 
 where first_name='Nancy' 
 得到查询结果:12000 
 -- step 2:查询工资大于12000的员工 
 --(12000是谁?如果nancy涨工资呢?)
  select employee_id , first_name 
  from employees 
  where salary>12000; 
  -- step 3:合并替换(由sql语句替换具体的值) 
  select employee_id , first_name 
  from employees
   where salary>(
   select salary 
   from employees
    where first_name='Nancy');


例:查询与Nancy同一部门的员工信息


-- step 1:查询Nancy的部门 
select department_id 
from employees 
where first_name = 'Nancy';
 得到结果:100 
 -- step 2:查询部门编号为100的员工信息 
 select department_id , first_name ,department_id 
 from employees 
 where department_id =100; 
 -- step 3:合并替换(由sql语句替换具体的值) 
 select department_id , first_name ,department_id 
 from employees where department_id =(
 select department_id 
 from employees
  where first_name='Nancy');


2、单列多值子查询

  • 概念:子查询结果出现多个值时,可以利用该值进行二次查询。

    例:查询与John同一部门的员工信息


-- step 1:查询John的部门 
select department_id 
from employees 
where first_name ='John'; 
得到结果:50、80、100 
-- step 2:查询属于50、80、100号部门的员工
 select * from employees
  where department_id 
  in(50,80,100); 
  -- step 3:合并替换(由sql语句替换具体的值) 
  select * from employees 
  where department_id in(
  select department_id 
  from employees 
  where first_name='John');


3、多列多值子查询

  • 概念:子查询结果为多值并且由多列构成,一般我们用于from后面,作为数据来源虚拟表。

    例:查询工资最高的前5行

-- step 1:将数据进行排序 
select sum(salary)from employees
 order by salary; 
 limit 5; 
 -- step 2:将子查询结果一张虚表再次处理 
 select sum(salary) 
 from  (
 select salary 
 from employees 
 order by salary 
 desc limit 5 ) as e; 
 -- MYSQL会把多列多值子查询当成一张虚拟表,必须为它定义别名,as可以省略


四、关系数据

  • 数据高耦合
  • 6.png
  • 通过部门编号能找到部门
  • 7.png
  • 部门的数据改名字就可以了,数据与数据之间耦合度就降低了
  • 8.png
  • 外键就是关系列,关系字段,用来表示外部关系,员工表的id是主键,唯一标识,不能为空,外键表明数据关系


9.png

通常就是一张表的外键指向另外一张表的主键

10.png


外键不能乱写,但是可以不写,表示没有部门

11.png

12.png


总结:在表中用于数据关系的字段,可以使用该字段中的数据,找到另外一张表,与之匹配,称之为外键


概念:有时我们不能单从一张表中看出数据的明细,它往往是一个编号,这个编号主要用于告诉我

   们到哪去寻找该数据的明细。


 


   例如:我们无法从 employees 表中看出员工的部门具体是什么,它只有一个编


   ( department_id ),必须通过编号到 department(部门表) 表中才能找到部门的详细信息

13.png

通过编号到 department 表中寻找对应的数据

14.png

可以看出 emplyees 表中的 department_id 与 department 表中的 department_id 是有关系

的,所以我们把该列数据称之为关系数据。

而该列称为外键。


外键

   作用:建立(说明)表与表、数据与数据之间的关系,例如 employees 表中的 department_id

   特点:

1. 外键的值一般来源于另外一张表主键的值,并且要满足参照完整性。
2. 外键在表连接时通常作为连接条件使用。
3.用于存储数据关系,外键指向了另外一张表的主键。

15.png


五、表连接

作用:当查询的数据需要从多张表中获取时,需要将多张表连接起来进行查询。

1、内连接(inner join)

语法:

select 表1.列名,... ,表2.列名,...
 from 表1 别名 
 inner join 表2 别名 
 on 连接条件;

t1,t2是表的别名,用于在查询时进行区分,明确查询数据来源于那张表

例:查询员工和部门的信息


select e.*,d.* 
from employees e inner join departments d 
on e.department_id = d.department_id;


特点:两张表中只要满足连接条件的数据才显示,不管是哪一张表的数据,只要不满足连接条件一定不显示。

16.png

2、左外连接(left join)

语法:

select 左表.列名,... ,右表.列名 
from 左表 别名 
left outer join 右表 别名 
on 连接条件;

例:查询员工及所属部门信息


select e.*,d.* 
from employees e 
left outer join departments d 
on e.department_id = d.department_id;

3、右外链接(right outer join)


语法:

select 左表.列名,... ,右表.列名,... 
from 左表 
right outer join 右表 on 连接条件;

例:–查询员工及所在部门信息


select e.*,d.*
 from employees e 
 right outer join departments d 
 on e.department_id = d.department_id;


特点:右表中无论是否满足连接条件都显示,左表中数据满足连接条件才显示,不满足就不显示。


注意:实战开发时,左外连接使用最多。内连接的inner关键字和外连接的outer关键字可以省略


3、多表链接

语法:

select 表1.列名,...,表2.列名,...,表3.列名,...
 from 表1 left join 表2 
 on 连接条件 
 left join 表3 
 on 连接条件 left join...


例:查询员工所在部门以及部门地址的信息


select e.*,d.*,l.* 
from employees e 
left join departments d 
on e.department_id = d.department_id 
left join locations l 
on d.location_id = l.location_id;


注意:实战中,表连接不能超过3张表,否则会有性能问题。

17.png

4、自连接

-- 查询员工与其经理的信息
select t1.*,t2.*
from employees t1 left join employees t2
on t1.manager_id = t2.employee_id;
-- 5. *查询员工的基本信息,附加其上级的姓名 (自己链接自己)
SELECT t1.*,t2.first_name 上级姓名
from employees  t1 left join employees t2
on t1.manager_id=t2.employee_id;
select * from employees
-- 6. *求入职日期相同(年月日相同)的员工(自己链接自己) 
select t1.*,t2.*
from employees t1 left join employees t2
on t1.hiredate=t2.hiredate;
-- 7. *显示各个部门经理的基本工资(自己链接自己)
SELECT t2.first_name 上级姓名,t2.salary 工资
from employees  t1 left join employees t2
on t1.manager_id=t2.employee_id;
select * from employees
相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
缓存 关系型数据库 MySQL
MySQL索引策略与查询性能调优实战
在实际应用中,需要根据具体的业务需求和查询模式,综合运用索引策略和查询性能调优方法,不断地测试和优化,以提高MySQL数据库的查询性能。
243 66
|
27天前
|
SQL 关系型数据库 MySQL
【MySQL基础篇】多表查询(隐式/显式内连接、左/右外连接、自连接查询、联合查询、标量/列/行/表子查询)
本文详细介绍了MySQL中的多表查询,包括多表关系、隐式/显式内连接、左/右外连接、自连接查询、联合查询、标量/列/行/表子查询及其实现方式,一文全面读懂多表联查!
【MySQL基础篇】多表查询(隐式/显式内连接、左/右外连接、自连接查询、联合查询、标量/列/行/表子查询)
|
1天前
|
缓存 关系型数据库 MySQL
【深入了解MySQL】优化查询性能与数据库设计的深度总结
本文详细介绍了MySQL查询优化和数据库设计技巧,涵盖基础优化、高级技巧及性能监控。
10 0
|
1月前
|
存储 Oracle 关系型数据库
索引在手,查询无忧:MySQL索引简介
MySQL 是一款广泛使用的关系型数据库管理系统,在2024年5月的DB-Engines排名中得分1084,仅次于Oracle。本文介绍MySQL索引的工作原理和类型,包括B+Tree、Hash、Full-text索引,以及主键、唯一、普通索引等,帮助开发者优化查询性能。索引类似于图书馆的分类系统,能快速定位数据行,极大提高检索效率。
59 8
|
1月前
|
SQL 关系型数据库 MySQL
MySQL 窗口函数详解:分析性查询的强大工具
MySQL 窗口函数从 8.0 版本开始支持,提供了一种灵活的方式处理 SQL 查询中的数据。无需分组即可对行集进行分析,常用于计算排名、累计和、移动平均值等。基本语法包括 `function_name([arguments]) OVER ([PARTITION BY columns] [ORDER BY columns] [frame_clause])`,常见函数有 `ROW_NUMBER()`, `RANK()`, `DENSE_RANK()`, `SUM()`, `AVG()` 等。窗口框架定义了计算聚合值时应包含的行。适用于复杂数据操作和分析报告。
75 11
|
1月前
|
存储 关系型数据库 MySQL
mysql怎么查询longblob类型数据的大小
通过本文的介绍,希望您能深入理解如何查询MySQL中 `LONG BLOB`类型数据的大小,并结合优化技术提升查询性能,以满足实际业务需求。
127 6
|
2月前
|
SQL 前端开发 关系型数据库
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
SpringBoot使用mysql查询昨天、今天、过去一周、过去半年、过去一年数据
83 9
|
2月前
|
缓存 监控 关系型数据库
如何优化MySQL查询速度?
如何优化MySQL查询速度?【10月更文挑战第31天】
194 3
|
2月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第27天】本文深入探讨了MySQL的索引策略和查询性能调优技巧。通过介绍B-Tree索引、哈希索引和全文索引等不同类型,以及如何创建和维护索引,结合实战案例分析查询执行计划,帮助读者掌握提升查询性能的方法。定期优化索引和调整查询语句是提高数据库性能的关键。
461 1
|
2月前
|
监控 关系型数据库 MySQL
数据库优化:MySQL索引策略与查询性能调优实战
【10月更文挑战第26天】数据库作为现代应用系统的核心组件,其性能优化至关重要。本文主要探讨MySQL的索引策略与查询性能调优。通过合理创建索引(如B-Tree、复合索引)和优化查询语句(如使用EXPLAIN、优化分页查询),可以显著提升数据库的响应速度和稳定性。实践中还需定期审查慢查询日志,持续优化性能。
238 0