MySQL —— 复合查询
目录
MySQL复合查询
一、基本查询回顾
二、多表查询
三、自连接
四、子查询
1. 单行子查询
2. 多行子查询
3. 多列子查询
4. 在from子句中使用子查询
五、合并查询
MySQL复合查询
一、基本查询回顾
前面我们讲解的mysql表的查询都是对单表进行查询,在实际开发中这远远不够。
部门表如下:
员工表如下:
工资表如下:
现做如下查询:
1. 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J
select ename, sal from emp where (sal>500 or job='MANAGER') and ename like 'J%';
2. 按照部门号升序而雇员的工资降序排序
select deptno,sal from emp order by deptno, sal desc;
3. 使用年薪进行降序排序
select ename, sal*12+ifnull(comm,0) as '年薪' from emp order by 年薪 desc;
4. 显示工资最高的员工的名字和工作岗位
select ename, job from EMP where sal = (select max(sal) from EMP);
5. 显示工资高于平均工资的员工信息
select ename, sal from emp where sal>(select avg(sal) from emp);
6. 显示每个部门的平均工资和最高工资
select deptno, avg(sal) 平均工资, max(sal) 最高工资 from emp group by deptno;
7. 显示平均工资低于2000的部门号和它的平均工资
select deptno, avg(sal) as 平均工资 from emp group by deptno having 平均工资<2000;
8. 显示每种岗位的雇员总数,平均工资
select job,count(*), format(avg(sal),2) from emp group by job;
二、多表查询
实际开发中往往数据来自不同的表,所以需要多表查询。本节我们用一个简单的公司管理系统,有三张表emp,dept,salgrade来演示如何进行多表查询。
- 在进行多表查询时,只需要将多张表的表名依次放到from子句之后,用逗号隔开即可,这时MySQL将会对给定的这多张表取笛卡尔积,作为多表查询的初始数据源。
- 多表查询的本质,就是对给定的多张表取笛卡尔积,然后在笛卡尔积中进行查询。
所谓的对多张表取笛卡尔积,就是得到这多张表的记录的所有可能有序对组成的集合,比如下面对员工表和部门表进行多表查询,由于查询语句中没有指明筛选条件,因此最终得到的结果便是员工表和部门表的笛卡尔积。(emp有14行记录,dept有4行记录。没一行emp的记录都对应4行dept记录)
需要注意的是,对多张表取笛卡尔积后得到的数据并不都是有意义的,比如对员工表和部门表取笛卡尔积时,员工表中的每一个员工信息都会和部门表中的每一个部门信息进行组合,而实际一个员工只有和自己所在的部门信息进行组合才是有意义的,因此需要从笛卡尔积中筛选出员工的部门号和部门的编号相等记录(我们只要emp表中的deptno = dept表中的deptno字段的记录)。如下:
进行笛卡尔积的多张表中可能会存在相同的列名,这时在选中列名时需要通过表名.列名
的方式进行指明。
显示部门号为10的部门名,员工名和工资
由于部门名只有部门表中才有,而员工名和员工工资只有员工表中才有,因此需要同时使用员工表和部门表进行多表查询,在where子句中指明筛选条件为员工的部门号等于部门编号,并且部门号为10的记录。如下:
select dname,ename,sal from emp,dept where emp.deptno=dept.deptno and emp.deptno=10;
显示各个员工的姓名、工资和工资级别
由于员工名和工资只有员工表中才有,而工资级别只有工资等级表中才有,因此需要同时使用员工表和工资等级表进行多表查询,在where子句中指明筛选条件为员工的工资在losal和hisal之间的记录。如下:
select ename,sal,grade from emp,salgrade where sal between losal and hisal;
- 员工表和工资等级表的笛卡尔积中,将每一个员工的信息和每一个工资等级的信息都进行了组合,而实际一个员工只有和自己的工资对应的工资等级信息进行组合才是有意义的。
- 因此需要根据各个工资等级的最低工资和最高工资判断一个员工是否属于该工资等级,进而筛选出有意义的记录。
三、自连接
- 自连接是指在同一张表进行连接查询,也就是说我们不仅可以取不同表的笛卡尔积,也可以对同一张表取笛卡尔积。
- 如果一张表中的某个字段能够将表中的多条记录关联起来,那么就可以通过自连接将表中通过该字段关联的记录组合起来。
显示员工FORD的上级领导的编号和姓名
--使用到表的别名
--from emp worker, emp leader,给自己的表起别名,因为要先做笛卡尔积,所以别名可以先识别
select leader.empno,leader.ename from emp worker,emp leader
where worker.ename='FORD' and worker.mgr=leader.empno;
四、子查询
- 子查询是指嵌入在其他SQL语句中的查询语句,也叫嵌套查询。
- 子查询可分为单行子查询、多行子查询、多列子查询,以及在from子句中使用的子查询。
1. 单行子查询
单行子查询,是指返回单行单列数据的子查询。
显示SMITH同一部门的员工
select * from emp where deptno = (select deptno from emp where ename='smith');
2. 多行子查询
多行子查询,是指返回多行单列数据的子查询
in关键字;查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的
select ename, job, sal, deptno from emp
where job in(select distinct job from emp where deptno=10) and deptno!=10;
先查询10号部门有哪些工作岗位,在查询时最好对结果进行去重,因为10号部门的某些员工的工作岗位可能是相同的。如下:
然后将上述查询作为子查询,在查询员工表时在where子句中使用in关键字,判断员工的工作岗位是子查询得到的若干岗位中的一个,如果是则符合筛选条件,由于要求筛选出来的员工不包含10号部门的,因此还需要在where子句中指明筛选条件为部门号不等于10。如下:
all关键字;显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号
select ename,sal,deptno from emp where sal > all (select distinct sal from emp where deptno=30);
先查询30号部门员工的工资,在查询时最好对结果进行去重,因为30号部门的某些员工的工资可能是相同的。如下:
然后将上述查询作为子查询,在查询员工表时在where子句中使用all关键字,判断员工的工资是否高于子查询得到的所有工资,如果是则符合筛选条件。如下:
any关键字:显示工资比30号部门的任意员工的工资高的员工的姓名、工资和部门号,包含30号部门的员工
3. 多列子查询
多列子查询,是指返回多列数据的子查询。
显示和SMITH的部门和岗位完全相同的员工,不包含SMITH本人
select * from emp
where (deptno, job)=(select deptno,job from emp where ename='SMITH') and ename!='SMITH';
先查询SMITH所在部门的部门号和他的岗位。如下:
然后将上述查询作为子查询,在查询员工表时在where子句中,指明筛选条件为部门号和岗位等于子查询得到的部门号和岗位,并且员工的姓名不为SMITH即可。如下:
注意:
- 多列子查询得到的结果是多列数据,在比较多列数据时需要将待比较的多个列用圆括号括起来。
- 多列子查询返回的如果是多行数据,在筛选数据时也可以使用in、all和any关键字。
4. 在from子句中使用子查询
- 子查询语句不仅可以出现在where子句中,也可以出现在from子句中。
- 子查询语句出现from子句中,其查询结果将会被当作一个临时表使用。
显示每个高于自己部门平均工资的员工的姓名、部门、工资和部门的平均工资
首先查询每个部门的平均工资。如下:
由于显示信息中包含部门的平均工资,需要同时使用员工表和上述的查询结果进行多表查询,这时可以将上述查询作为子查询放在from子句中,然后对员工表和临时表取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号,并且员工的工资大于临时表中的平均工资。如下:
注意: 在from子句中使用子查询时,必须给子查询得到的临时表取一个别名,否则查询将会出错。
显示每个部门工资最高的员工的姓名、工资、部门和部门的最高工资。
先查询每个部门的最高工资。如下:
将上述查询作为子查询放在from子句中,然后对员工表和临时表取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号,并且员工的工资等于临时表中的最高工资。如下:
显示每个部门的部门名、部门编号、所在地址和人员数量
查询每个部门的人员数量。如下:
将上述查询作为子查询放在from子句中,然后对员工表和临时表取笛卡尔积,在where子句中指明筛选条件为员工的部门号等于临时表中的部门号即可。如下:
此外,除了上述子查询+多表查询的方式外,也可以只使用多表查询解决该问题。
- 先对员工表和部门表取笛卡尔积。
- 在where子句中指明筛选条件为员工的部门号等于部门的编号,筛选出有意义的记录。
- 在order by子句中指明按照部门号进行分组,分别统计出每个部门的人数。
但由于题目同时要求显示每个部门的部门名和所在地址,因此在group by子句中需要添加按照部门名和地址进行分组。如下:
注意:
- 因为在select语句中新增了要显示部门名和所在地址,因此需要在group by子句中也添加这两个字段,表明当部门号相同时按照部门名进行分组,当部门名也相同时继续按照所在地址进行分组。
- 但实际在上述场景中部门号相同的记录,它们的部门名和所在地址也一定是相同的,因此在我们看来group by中继续添加这两个字段没什么意义,但MySQL语句要求我们必须添加。
五、合并查询
合并查询,是指将多个查询结果进行合并,可使用的操作符有union和union all。
- union用于取得两个查询结果的并集,union会自动去掉结果集中的重复行。
- union all也用于取得两个查询结果的并集,但union all不会去掉结果集中的重复行。
显示工资大于2500或职位是MANAGER的员工
查询工资大于2500的员工的SQL如下:
查询职位是MANAGER的员工的SQL如下:
要查询工资大于2500或职位是MANAGER的员工,可以使用or操作符将where子句中的两个条件关联起来。如下:
在合并查询这里,可以使用union操作符将上述的两条查询SQL连接起来,这时将会得到两次查询结果的并集,并且会对合并后的结果进行去重。如下:
此外,也可以使用union all操作符将上述的两条查询SQL连接起来,这时将也会得到两次查询结果的并集,但不会对合并后的结果进行去重。如下:
注意:
- 待合并的两个查询结果的列的数量必须一致,否则无法合并。
- 待合并的两个查询结果对应的列属性可以不一样,但不建议这样做。
MySQL —— 复合查询相关推荐
- MySQL复合查询(多表查询)
文章目录 一.基本查询回顾 二.多表查询 1.最基本的复合查询 三.自查询 四.子查询 1.单行子查询 2.多行子查询 (1)in关键字 (2)all关键字 (3)any关键字 3.多列子查询 4.在 ...
- mysql select符合查询_数据库select group by 和having语句 多表连接查询 复合查询
1.SELECT --group by 子句 group by子句按照指定的列column_name对表数据进行分组 group by 后面跟的列也叫分组特性列 使用group by后,能选择的列 ...
- MySQL(四)复合查询与联合查询
文章目录 复合查询 复合函数 AVG COUNT SUM MAX MIN 分组查询 GROUP BY HAVING 联合查询 内连接 外连接 左连接 右连接 自连接 子查询 合并查询 UNION UN ...
- MySQL数据检索+查询+全文本搜索
[0]README 0.1)本文部分文字描述转自"MySQL 必知必会",旨在review"MySQL数据检索+查询+全文本搜索" 的基础知识: [1]使用子查 ...
- mysql 组合查询_MySQL组合查询教程
#MYSQL#这是我MySQL的第八篇教程.本篇主要介绍的是MySQL的组合查询的用法.在大多数的SQL查询中都只包含从一个或者多个表中返回数据的单条SELECT语句,MySQL其实也支持允许执行多条 ...
- Mysql简介和Mysql优化查询的方法
MySQL 是瑞典的MySQL AB公司开发的一个可用于各种流行操作系统平台的关系数据库系统,它具有客户机/服务器体系结构的分布式数据库管理系统.MySQL 完全适用于网络,用其建造的数据库可在因特网 ...
- mysql数据库查询笔记_mysql笔记: 查询
mysql笔记: 查询 查询准备 CREATE DATABASE search; use search; # 学生表(student):学号.姓名.性别.出生日期.班级 CREATE TABLE st ...
- Elasticsearch(三)——Es搜索(简单使用、全文查询、复合查询)、地理位置查询、特殊查询、聚合操作、桶聚合、管道聚合
Elasticsearch(三)--Es搜索(简单使用.全文查询.复合查询).地理位置查询.特殊查询.聚合操作.桶聚合.管道聚合 一.Es搜索 这里的 Es 数据博主自己上网找的,为了练习 Es 搜索 ...
- Mysql复合索引最左匹配原则以及索引失效条件
Mysql复合索引最左匹配原则以及索引失效条件 复合索引最左匹配原则 用EXPLAIN 来查看语句是否用到了索引 索引失效的条件 一般性建议 复合索引最左匹配原则 复合索引又叫联合索引.两个或更多个列 ...
最新文章
- 基于模糊聚类的色彩迁移算法
- 操作系统(二十九)预防死锁
- 依赖注入的三种方式_一起学Spring之三种注入方式及集合类型注入
- 嵌入式linux svn,Linux下配置subversion使其支持svn+ssh方式访问
- intellij idea搭建springboot
- 基础算法 —— 调度问题 —— 流水调度问题
- Eclipse的详细安装步骤
- 数据集市的建立方法_在集市上工作时如何建立专业网络
- tcxgrid主从结构显示多行_快速跟随型主从结构多电机同步控制
- jQuery easyUI Pagination控件自定义div分页(不用datagrid)
- Cognos8.3 + oracle9i数据集市 建cube性能调整
- Shell函数和正则表达式
- NSString中如何正确判断包含一个变量字串NSString
- css 图片大小自适应div,css让图片自适应容器(div)大小
- 数字图像处理期末复习题
- 注册表右键取得管理员权限
- VBA中启动其它程序
- 【Base64是什么?】
- javaScript 关于console的理解
- ubuntu 12.10起用g++4.7 编译C++11
热门文章
- 提高微信群引流的有效方法
- 四维反对称矩阵matlab,matlab-线性代数 判断 矩阵的对称、实对称、反对称
- 详解霍尔元件的分类与特性
- 目标检测——SPPNet【含全网最全翻译】
- 安防监控VS个人隐私: 360小水滴今日关闭, 为何网友仍期待公共场所直播?
- 樊登36个问题建立亲密关系_亚瑟阿伦的36个问题:打造亲密关系
- Android HIDL机制学习
- QT combox的使用示例(输入后捕捉enter键,以及输入编辑框如何加输入限制(正则表达式))
- java 英文单词排序_java对英文单词排序
- matlab nlinfit与lsqcurvefit区别