当前位置: 首页 > news >正文

八.MySQL复合查询

一.基本查询回顾

分组统计 group by

函数作用示例语句说明
count(*)统计记录条数select deptno, count(*) from emp group by deptno;每个部门有多少人?
sum(sal)某字段求和select deptno, sum(sal) from emp group by deptno;每个部门总工资
avg(sal)求平均值select deptno, avg(sal) from emp group by deptno;每个部门平均工资
max(sal)最大值select job, max(sal) from emp group by job;每个职位最高工资
min(sal)最小值select job, min(sal) from emp group by job;每个职位最低工资

1.查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J

(sal>500 or job=MANAGER)and(ename like'J%')

2.按照部门号升序而雇员的工资降序排序

order by depton asc , sal desc

3.使用年薪进行降序排序

年薪=sal*12+comm  comm有的为NULL,任何值加上NULL都为NULL 但我们运算时遇到NULL要把他视为0

select ename,sal*12+ifnull(comm,0) 年薪 from emp order by 年薪 desc;

4.显示工资最高的员工的名字和工作岗位

        1.先找出最高工资为多少

        2.再根据最高工资筛选出 符合条件的

select max(sal) from emp;

select ename,job form emp where sal=(select max(sal) from emp);

5.显示工资高于平均工资的员工信息

6.显示每个部门的平均工资和最高工资

1.平均薪资 select avg(sal) from emp;

2.最高新增 select max(sal) from emp;

3. 根据部门分组  select * from emp group by(deptno);

select deptno,avg(sal), max(sal) from emp group by(deptno);

format(值,保留几位小数)

7.显示平均工资低于2000的部门号和它的平均工资

        1.group by 对表按部门号进行分组 

        2.having 对分组聚合后的结果进行筛选

        3.select avg(sal) 输出平均薪资 

select deptno,avg(sal) 平均薪资 from EMP group by deptno  having 平均薪资<2000;

8.显示每种岗位的雇员总数,平均工资

        1.按岗位分组

        2.分完组 count(*)计算每个组的行数  avg(sal)计算每个组的平均薪资

        3.select 输出

 select  job,count(*) 岗位数,format(avg(sal),2) 平均薪资 from EMP group by job;

二.多表查询

实际开发中往往数据来自不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张表EMP,DEPT,SALGRADE来演示如何进行多表查询。
案例:
显示雇员名、雇员工资以及所在部门的名字因为上面的数据来自EMP和DEPT表,因此要联合查询

DEPT 表(部门表)

字段含义
deptno部门编号
dname部门名称
loc部门所在地
EMP 员工表 这是员工信息表, deptno 是外键,对应 DEPT 表中的主键。
字段含义
empno员工编号
ename员工姓名
job岗位
mgr上级编号
hiredate入职日期
sal工资
comm奖金
deptno所属部门编号

select * from EMP,DEPT;

没有添加任何连接条件时,MySQL 会把 EMP 表的每一行和 DEPT 表的每一行全部组合,形成 笛卡尔积

假设:

  • EMP 表有 14 条记录

  • DEPT 表有 4 条记录

那么结果是:14 × 4 = 56 条记录

每一条记录是:EMP 表中一名员工 + DEPT 表中任一部门的组合。这个结果毫无实际意义!

联表:1.where 添加连接条件

where e.deptno=d.deptno

把员工分配到他们真正所在的部门,避免出现无意义的组合(也就是避免笛卡尔积)。

1.显示部门号为10的部门名,员工名和工资

select dname,ename,sal,e.deptno from EMP e,DEPT d

where e.deptno=d.deptno and e.deptno=10;

2.显示各个员工的姓名,工资,及工资级别

select ename,sal,grade from EMP e,SALGRADE s where sal between losal and hisal;

between 最小值 and 最大值 是否在该范围内(含边界值)

between ... and ... 是 SQL 中的一个 范围判断操作符,它表示某个值是否在两个值之间(包含边界)

联表:2.join 表 on 添加连接条件

JOIN 是 SQL 中用于 多表连接查询 的语法,它通过指定的条件把多张表的数据连接成一张大表

类型作用说明
INNER JOIN两表匹配成功才显示(最常用)
LEFT JOIN左表全保留,右表能对上就显示,不能对上为 NULL
RIGHT JOIN右表全保留,左表不能对上为 NULL
FULL JOIN两边都保留,不匹配的补 NULL(MySQL 不支持)
项目JOINWHERE 条件连接
写法FROM A JOIN B ON 条件FROM A, B WHERE A.id = B.id
推荐程度✅ 推荐,更清晰、规范🟡 可用,老写法,容易出错
逻辑结构显式地指定连接方式模糊:连接条件和筛选条件混在一起
支持多种连接✅ 支持 INNER、LEFT、RIGHT 等🚫 只能做 INNER JOIN 效果
可读性✅ 强🟡 较弱

把员工和他们所在的部门名对应起来

1.where:

from 引入两个关联的表  where 添加连接条件

2.join on:

from 引入一个表

join 再引入关联的表  on  连接条件

JOIN 负责“怎么连”,WHERE 负责“连完之后怎么筛”。

三.自连接

自连接是指在同一张表连接查询.

用于处理 表中记录之间有层级关系 的场景,例如:

  • 员工表中,mgr 字段是上级的 empno(员工编号)

  • 我们需要通过员工的 mgr 去找到他上级是谁(也在同一张表里)

查出“FORD的上级领导编号和姓名”

1.先找到FORD的mgr领导的编号  2.再根据mgr领导的编号找到领导的信息

        1.子查询方式:

select empno,ename,job,mgr from EMP

where (select mgr from EMP where ename='FORD')=empno;

查找ename=‘FORD’员工的mgr领导编号select mgr from EMP where ename='FORD'

        2.自连接

select leader.empno,leader.ename from EMP leader, EMP worker

where leader.empno = worker.mgr and worker.ename='FORD';

where leader.empno = worker.mgr 找到每个员工对应的领导   and worker.ename='FORD';找到指定员工的领导

注意:要显示领导的信息select leader.empno,leader.ename

四.子查询

1.单列子查询

返回一行记录的子查询
1.显示SMITH同一部门的员工

2.多行子查询

1.in在结果集合中匹配任意一个

查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的

        1.10号部门的工资岗位种类有什么

select distinct job from EMP where deptno=10;distinct去重

        2.找属于该工作岗位表中的员工 

job in (工作岗位表)

        3.去掉10号部门人

deptno!=10

 

2.all 大于所有返回值才成立

显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号

方法1:

        1.部门30员工的最大值

max(als) where deptno=30;

        2.大于部门30最大值的员工

>max

select ename, sal, deptno from EMP

where sal > (select max(sal) from EMP where deptno=30);

比30号部门的最大值大

方法2:

select ename, sal, deptno from EMP

where sal > all(select sal from EMP where deptno=30);

比30号部门all所有值大

3.any 只要大于其中一个值就行

显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门
的员工)

select ename, sal, deptno from EMP where sal > any(select sal from EMP where deptno=30);

3.多列子查询

多行子查询 都是根据一个字段来进行查询,如果多个字段呢?

eg.查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人

4.在from子句中使用子查询

子查询语句出现在from子句中。这里要用到数据查询的技巧,把一个子查询当做一个临时表使用。

1.显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资

        1.group by + avg() 得到部门+部门平均工资的表

        2.将员工表,部门工资表进行笛卡儿积 where 连接条件为部门号相同。这样融合后的表就有所有员工的薪资+每个部门的平均薪资

select ename, t1.deptno, sal, format(sal,2) from EMP t1,

(select deptno,avg(sal) 部门资 from EMP group by deptno) t2

where t1.deptno=t2.deptno and  t1.sal>t2.部门资 ;   

//注意一定要添加连接条件 t1.deptno=t2.deptno 取掉无效笛卡儿积

where 连接条件+筛选条件

2.查找每个部门工资最高的人的姓名、工资、部门、最高工资

        1.group by+max() 部门+部门最高薪资

        2.连接 where+连接条件(部门相同)+筛选条件(最高薪资相同)

select ename,t1.deptno,sal,t2.最高薪资 from EMP t1,

(select deptno,max(sal) 最高薪资 from EMP group by deptno) t2

where t1.deptno=t2.deptno and t1.sal=t2.最高薪资;

3.显示每个部门的信息(部门名,编号,地址)和人员数量

        1.group by+count(*) 部门号+每个部门人数

        2.from DEPT连接表包含部门信息

select DEPT.deptno, dname, mycnt, loc from DEPT,

(select deptno,count(*) mycnt  from EMP group by deptno) t

where DEPT.deptno=t.deptno;

五.合并查询(union/ union all)

1.union (去重)

该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。

eg.将工资大于2500或职位是MANAGER的人找出来

2.union all(不去重)

该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。

eg.将工资大于2500或职位是MANAGER的人找出来

注意:

  • UNIONUNION ALL 合并的 列数必须相同,数据类型必须兼容

  • 默认按第一个 SELECT 的列名作为最终输出表头。

  • 如果你要排序,必须加在最后一个 SELECT 之后:

http://www.xdnf.cn/news/792649.html

相关文章:

  • 书籍在其他数都出现k次的数组中找到只出现一次的数(7)0603
  • 实战商品订单秒杀设计实现
  • Juce实现Table自定义
  • 高效背诵英语四级范文
  • JS逆向-基础入门案例(详细步骤)
  • 39、响应处理-【源码分析】-内容协商原理
  • Ubuntu20.04用root(管理员身份)启动vscode
  • 第三发 DSP 点击控制系统
  • [概率论基本概念4]什么是无偏估计
  • 【电力电子】什么是并网?为什么要并网?并网需要考虑哪些因素?
  • 黑盒(功能)测试基本方法
  • 如何从0开始搭建自动化测试框架?
  • Docker 部署前后端分离项目
  • 中英混合编码解码全解析
  • 飞牛fnNAS使用群辉DSM系统
  • C#基础语法
  • DMA-BUF与mmap共享内存对比分析
  • 辩证唯物主义精要
  • 【Golang】使用gin框架导出excel和csv文件
  • 基于Python协同过滤的电影推荐系统研究
  • DDR信号线走线关键点
  • Vert.x学习笔记-EventLoop与Handler的关系
  • WebTracing:一站式前端埋点监控解决方案
  • 多线程编程中的重要概念
  • CSP模式下如何保证不抖动
  • 查询去重使用 DISTINCT 的性能分析
  • Ubuntu安装Docker命令清单(以20.04为例)
  • 文件批量重命名
  • Tiktok App 登录账号、密码、验证码 XOR 加密算法
  • C++指针加减法详解:深入理解指针运算的本质