MySQL 复合查询

文章目录

基本查询回顾

  1. 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J
sql 复制代码
select * from emp where (salary>500 or job='MANAGER') and ename like 'J%';
select * from emp where (salary>500 or job='MANAGER') and substring(ename,1,1)='J';
  1. 按照部门号升序而雇员的工资降序排序
sql 复制代码
select * from emp order by deptno asc,sal desc;
  1. 使用年薪进行降序排序
sql 复制代码
select ename,sal,comm,sal*12+ifnull(comm,0) as 年薪 from emp order by 年薪 desc; 
  1. 显示工资最高的员工的名字和工作岗位
sql 复制代码
select ename,job from emp where sal=(select max(sal) from emp);
  1. 显示工资高于平均工资的员工信息
sql 复制代码
select * from emp where sal > (select avg(sal) from emp);
  1. 显示每个部门的平均工资和最高工资
sql 复制代码
// 保留2位精度统计
select deptno,format(avg(sal),2),max(sal) where emp group by deptno;
  1. 显示平均工资低于2000的部门号和它的平均工资
sql 复制代码
// 分组有多个部门,每个部门的平均工资
// having对分组之后的结果进行判断
select deptno,avg(sal) 平均工资 from emp group by deptno having 平均工资 < 2000  
  1. 显示每种岗位的雇员总数,平均工资
sql 复制代码
select job,count(job) 人数,format(avg(sal),2) 平均工资 from emp group by job;

显示出每个岗位有多少个人


多表笛卡尔积

  1. 两张表进行组合,第一张表中的第一条信息和第二张表中的4条信息进行组合/穷举


  1. 显示雇员名、雇员工资以及所在部门的名字
sql 复制代码
// 连接两张表进行查询
select ename,sal,dname from dept,emp where emp.deptno=dept.deptno;
  1. 显示部门号为10的部门名,员工名和工资
sql 复制代码
select ename,sal,dname,dept.deptno from emp,dept where emp.deptno=dept.deptno and emp.dpetno=10;
  1. 显示各个员工的姓名,工资,及工资级别
sql 复制代码
select ename,sal,grade,losal,hisal from emp,salgrade where sal between losal and hisal;

自连接

  1. 用同一张表进行笛卡尔积,但是要进行重命名
  1. 显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号--empno)
    先找FORD的领导编号
    根据领导编号找领导的信息
sql 复制代码
select ename,empno from emp where empno=(select mgr from emp where ename='FORD');


sql 复制代码
select e2.ename,e2.empno from emp e1,emp e2 where e1.ename='FORD' and e1.mgr=e2.empno;

子查询与where

子查询

  1. 子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询

单行子查询

  1. 返回一行记录的子查询
    显示SMITH同一部门的员工
sql 复制代码
select * from emp where deptno=(select deptno from emp where ename='SMITH'); 

多行子查询

  1. 返回多行记录的子查询
  2. in关键字,判断集合是否在列当中
    查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的
sql 复制代码
select ename,job,sal,deptno from emp where job in(select distinct job from where deptno=10) and
deptno <> 10;
  1. 并且知道对应的员工属于哪个部门的名字
sql 复制代码
select ename,job,sal,dname from
(select ename,job,sal,deptno from emp where job in 
(select distinct job from emp where deptno=10) and deptno<>10;)
and deptno <>10) as tmp ,dept where dept.deptno=tmp.deptno;
  1. all关键字;显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号
sql 复制代码
select * from emp where sal > (select max(sal) from emp where deptno=30);

all,比所有人的工资都高,就是比30号部门最高工资都高

sql 复制代码
select * from emp where sal > all(select distinct sal from emp where deptno=30);
  1. any关键字;显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)

任意指的是,比该部门中最小的大都行

sql 复制代码
select * from emp where sal > any(select distinct sal from emp where deptno=30);

多列子查询

  1. 单行子查询是指子查询只返回单列,单行数据;多行子查询是指返回单列多行数据,都是针对单列而言的,而多列子查询则是指查询返回多个列数据的子查询语句

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

sql 复制代码
select * from emp where (deptno,job)=(select deptno,job from emp where ename='SMITH) and ename <> 'SMITH'; 

总结:

  1. 目前全部的子查询,全部都在where子句中,充当判断条件

  2. 任何时候查询出来的逻辑结构,本质上在逻辑上也是表结构

  3. 子查询不仅可以出现在where后面,也可以出现在from后面 (把子查询当成一个临时表使用)

子查询与from

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

案例

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

sql 复制代码
// 查询分组后的部门号和平均工资
select deptno,avg(sal) from emp group by dpetno;
sql 复制代码
// 对员工表和部门的平均工资表做拼接
// 做笛卡尔积要部门号相同才有意义
select * from emp,(select deptno,avg(sal) from emp group by deptno) as tmp where emp.deptno=tmp.deptno;
sql 复制代码
select * from emp,(select deptno,avg(sal) as myavg from emp group by deptno) as tmp where emp.deptno=tmp.deptno and emp.sal > tmp.myavg;


在加一个条件,筛选出部门号和办公地点,要连接部门表和这个临时表

  1. 查找每个部门工资最高的人的姓名、工资、部门、最高工资
sql 复制代码
select ename,sal,t1.deptno,mymax from emp as t1,(select deptno,max(sal) mymax from emp group by deptno) as t2 where t1.deptno=t2.deptno and t1.sal=t2.mymax;
  1. 显示每个部门的信息(部门名,编号,地址)(dept)和人员数量
sql 复制代码
select t1.deptno,t1.dname,t1.loc,t2.dept_num from dept as t1,(select deptno,count(*) as dept_num from emp group by deptno) as t2 where t1.deptno=t2.deptno;
  1. COUNT(*) 是聚合函数,所以不需要在 GROUP BY 里出现。

  2. 在标准 SQL(如 MySQL 5.7+、PostgreSQL、SQL Server)中,SELECT 子句中的 所有非聚合列(如 DEPT.dname, DEPT.loc)必须出现在 GROUP BY 子句中,否则会报错:

  3. group by 要符合语法

使用多表(不推荐使用)

sql 复制代码
select DEPT.dname, DEPT.deptno, DEPT.loc,count(*) '部门人数' from EMP,
DEPT
where EMP.deptno=DEPT.deptno
group by DEPT.deptno,DEPT.dname,DEPT.loc;

总结

合并查询(不太重要)

  1. 合并多个select的执行结果,可以使用集合操作符 union,union all

union

  1. 该操作符用于取得两个结果集的并集 。当使用该操作符时,会自动去掉结果集中的重复行
  2. 使用union和all union 必须保证列的数量是相同的

案例

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

sql 复制代码
select * from emp where sal>2500 union select * from emp where job='MANAGER'; 

去重掉了重复项

union all

  1. 效果和union一样,但是不会去掉重复的信息

案例:

将工资大于25000或职位是MANAGER的人找出来

sql 复制代码
select * from emp where sal > 25000 union select * from emp where job='MANAGER';
相关推荐
阿巴斯甜1 小时前
Android 报错:Zip file '/Users/lyy/develop/repoAndroidLapp/l-app-android-ble/app/bu
android
Kapaseker1 小时前
实战 Compose 中的 IntrinsicSize
android·kotlin
xq95272 小时前
Andorid Google 登录接入文档
android
黄林晴4 小时前
告别 Modifier 地狱,Compose 样式系统要变天了
android·android jetpack
冬奇Lab16 小时前
Android触摸事件分发、手势识别与输入优化实战
android·源码阅读
城东米粉儿19 小时前
Android MediaPlayer 笔记
android
Jony_19 小时前
Android 启动优化方案
android
阿巴斯甜19 小时前
Android studio 报错:Cause: error=86, Bad CPU type in executable
android
张小潇20 小时前
AOSP15 Input专题InputReader源码分析
android
_小马快跑_1 天前
Kotlin | 协程调度器选择:何时用CoroutineScope配置,何时用launch指定?
android