MySQL——复合查询

目录

一、基本查询回顾

二、多表查询

三、自连接

四、子查询

[4.1 单行子查询(子查询结果为单列单行)](#4.1 单行子查询(子查询结果为单列单行))

[4.2 多行子查询(子查询结果为单列多行)](#4.2 多行子查询(子查询结果为单列多行))

[4.3 多列子查询](#4.3 多列子查询)

[4.4 在FROM子句中使用子查询](#4.4 在FROM子句中使用子查询)

五、合并查询


一、基本查询回顾

sql 复制代码
SHOW DATABASES;
USE test_select;
USE scott;
-- 基本查询回顾
-- 查询工资高于500或岗位为MANAGER的雇员,同时还需要满足他们的姓名首字母大写为J
SELECT * FROM emp;
SELECT * FROM emp WHERE (sal > 500 OR job = 'MANAGER') AND SUBSTRING(ename,1,1) = 'J'; 
SELECT * FROM emp WHERE (sal > 500 OR job = 'MANAGER') AND SUBSTRING(ename,1,2) = 'JA';
-- 按照部门号升序而雇员工资降序进行排序
SELECT * FROM emp ORDER BY deptno ASC,sal DESC;
SELECT ename,sal,deptno FROM emp ORDER BY deptno ASC,sal DESC;
-- 使用年薪进行降序排序
SELECT * FROM emp;
SELECT * FROM emp WHERE ename = 'SMITH';
SELECT sal*12 年薪 FROM emp WHERE ename = 'SMITH';
SELECT sal*12+comm 年薪 FROM emp WHERE ename = 'SMITH';
SELECT sal*12+IFNULL(comm,0) 年薪 FROM emp WHERE ename = 'SMITH';
SELECT sal*12+IFNULL(comm,0) 年薪 FROM emp;
SELECT sal*12+IFNULL(comm,0) 年薪 FROM emp ORDER BY 年薪 DESC;
-- 显示工资最高的员工的名字和工作岗位
SELECT MAX(sal) FROM emp;
SELECT * FROM emp WHERE sal = 5000;
SELECT * FROM emp WHERE sal = (SELECT MAX(sal) FROM emp);
SELECT ename,job FROM emp WHERE sal = (SELECT MAX(sal) FROM emp);
-- 显示每个部门的平均工资和最高工资
SELECT AVG(sal) 平均工资 FROM emp;
SELECT * FROM emp WHERE sal > (SELECT AVG(sal) FROM emp);
SELECT MAX(sal),AVG(sal) FROM emp;
SELECT MAX(sal) 最高,AVG(sal) 平均 FROM emp;
SELECT MAX(sal) 最高,AVG(sal) 平均 FROM emp GROUP BY deptno;
SELECT deptno,MAX(sal) 最高,AVG(sal) 平均 FROM emp GROUP BY deptno;
SELECT deptno,FORMAT(MAX(sal),2) 最高,FORMAT(AVG(sal),2) 平均 FROM emp GROUP BY deptno;
-- 显示平均工资低于2000的部门号和它的平均工资
SELECT AVG(sal) FROM emp;
SELECT AVG(sal) FROM emp GROUP BY deptno;
SELECT AVG(sal) 平均工资 FROM emp GROUP BY deptno;
SELECT deptno,AVG(sal) 平均工资 FROM emp GROUP BY deptno HAVING 平均工资<2000;
-- 显示每种岗位的雇员总数以及平均工资
SELECT job 岗位,COUNT(*) 雇员总数,FORMAT(AVG(sal),2) 平均工资 FROM emp GROUP BY job;

二、多表查询

多表查询步骤:

1.从第一张表中选出第一条记录,和第二张表的所有记录进行组合;

2.然后从第一张表中取第二条记录,和第二张表中的所有记录组合;

3.不加过滤条件,得到的结果为笛卡尔积;

例如SQL语句:

sql 复制代码
SELECT * FROM emp,dept;
sql 复制代码
-- 多表查询
-- 显示雇员名,雇员工资以及所在部门的名字
SELECT * FROM emp;
SELECT * FROM dept; 
SELECT * FROM emp,dept;
SELECT * FROM emp,dept WHERE emp.deptno = dept.deptno;
-- 显示部门号为10的部门名,员工名和工资
SELECT * FROM emp,dept WHERE emp.deptno = dept.deptno;
SELECT ename,dname,sal FROM emp,dept WHERE emp.deptno = dept.deptno AND emp.deptno = 10;
-- 显示各个员工的姓名、工资以及工资级别
SELECT * FROM emp;
SELECT * FROM salgrade;
SELECT * FROM emp,salgrade;
SELECT * FROM emp,salgrade WHERE sal BETWEEN losal AND hisal;
SELECT ename,sal,grade FROM emp,salgrade WHERE sal BETWEEN losal AND hisal;
SELECT * FROM emp t1,salgrade t2;
SELECT * FROM emp AS t1,salgrade AS t2;

三、自连接

自连接指的是对同一张表进行连接查询。

sql 复制代码
-- 自连接
-- 显示员工FORD的上级领导的编号和姓名
-- 方法1:子查询
SELECT * FROM emp;
SELECT mgr FROM emp WHERE ename = 'FORD';
SELECT ename,empno FROM emp WHERE mgr = 7566;
SELECT ename,empno FROM emp WHERE empno = 7566;
SELECT ename,empno FROM emp WHERE empno = (SELECT mgr FROM emp WHERE ename = 'FORD');
-- 方法2:自连接
SELECT * FROM emp e1,emp e2;
SELECT * FROM emp e1,emp e2 WHERE e1.ename = 'FORD';
SELECT * FROM emp e1,emp e2 WHERE e1.ename = 'FORD' AND e1.mgr = e2.empno;
SELECT e1.ename,e1.empno FROM emp e1,emp e2 WHERE e1.ename = 'FORD' AND e1.mgr = e2.empno;

四、子查询

子查询指的是SELECT语句嵌套在其它SQL语句中所形成的SELECT语句。

子查询一班出现在两个地方:

1.在WHERE子句中充当条件判断语句;

2.在FROM语句中作为临时表进行多表查询(笛卡尔积);

4.1 单行子查询(子查询结果为单列单行)

sql 复制代码
-- 子查询
-- 单行子查询
-- 显示与SMITH同一部门的员工
SELECT * FROM emp WHERE ename = 'SMITH';
SELECT deptno FROM emp WHERE ename = 'SMITH';
SELECT * FROM emp WHERE deptno = 20;
SELECT * FROM emp WHERE deptno = (SELECT deptno FROM emp WHERE ename = 'SMITH');
SELECT ename FROM emp WHERE deptno = (SELECT deptno FROM emp WHERE ename = 'SMITH');

4.2 多行子查询(子查询结果为单列多行)

sql 复制代码
-- 多行子查询
-- 查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10号部门自己的
-- 10号部门的工作岗位不止一个,要用IN关键字
SELECT job FROM emp WHERE deptno = 10;
SELECT DISTINCT job FROM emp WHERE deptno = 10;
SELECT ename,job,sal,deptno FROM emp WHERE job IN (SELECT DISTINCT job FROM EMP WHERE deptno = 10);
SELECT ename,job,sal,deptno FROM emp WHERE job IN (SELECT DISTINCT job FROM EMP WHERE deptno = 10) AND deptno <> 10;
SELECT * FROM (SELECT ename,job,sal,deptno FROM emp WHERE job IN (SELECT DISTINCT job FROM EMP WHERE deptno = 10) AND deptno <> 10) AS tmp,dept;
SELECT * FROM (SELECT ename,job,sal,deptno FROM emp WHERE job IN (SELECT DISTINCT job FROM EMP WHERE deptno = 10) AND deptno <> 10) AS tmp,dept WHERE tmp.deptno = dept.deptno;
SELECT ename,dname,job,sal,tmp.deptno FROM (SELECT ename,job,sal,deptno FROM emp WHERE job IN (SELECT DISTINCT job FROM EMP WHERE deptno = 10) AND deptno <> 10) AS tmp,dept WHERE tmp.deptno = dept.deptno;

-- ALL关键字;显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号
SELECT MAX(sal) FROM emp WHERE deptno = 30;
SELECT ename,sal,deptno FROM emp WHERE sal > 2850;
SELECT ename,sal,deptno FROM emp WHERE sal > (SELECT MAX(sal) FROM emp WHERE deptno = 30);
SELECT DISTINCT sal FROM emp WHERE deptno = 30;
SELECT ename,sal,deptno FROM emp WHERE sal > ALL(SELECT DISTINCT sal FROM emp WHERE deptno = 30);
-- ANY关键字;显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门的员工)
SELECT DISTINCT sal FROM emp WHERE deptno = 30;
SELECT ename,sal,deptno FROM emp WHERE sal > ANY (SELECT DISTINCT sal FROM emp WHERE deptno = 30);

4.3 多列子查询

sql 复制代码
-- 多行单列子查询:=
SELECT ename FROM emp WHERE (deptno,job) = (SELECT deptno,job FROM emp WHERE ename = 'SMITH') AND ename <> 'SMITH';
-- 多行多列子查询:IN
SELECT ename FROM emp WHERE (deptno,job) IN (SELECT deptno,job FROM emp WHERE ename = 'SMITH') AND ename <> 'SMITH'; 

4.4 在FROM子句中使用子查询

sql 复制代码
-- FROM子句中使用子查询
-- 显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资
SELECT AVG(sal) FROM emp;
SELECT AVG(sal) FROM emp GROUP BY deptno;
SELECT deptno,AVG(sal) FROM emp GROUP BY deptno;
SELECT * FROM emp,(SELECT deptno,AVG(sal) FROM emp GROUP BY deptno) tmp;
SELECT * FROM emp,(SELECT deptno,AVG(sal) FROM emp GROUP BY deptno) tmp WHERE emp.deptno = tmp.deptno;
SELECT * FROM emp,(SELECT deptno,AVG(sal) FROM emp GROUP BY deptno) tmp WHERE emp.deptno = tmp.deptno AND emp.sal > tmp.AVG(sal);
SELECT * FROM emp,(SELECT deptno,AVG(sal) myavg FROM emp GROUP BY deptno) tmp WHERE emp.deptno = tmp.deptno AND emp.sal > tmp.myavg;
SELECT ename,emp.deptno,sal,myavg FROM emp,(SELECT deptno,AVG(sal) myavg FROM emp GROUP BY deptno) tmp WHERE emp.deptno = tmp.deptno AND emp.sal > tmp.myavg;
SELECT * FROM dept,(SELECT ename,emp.deptno,sal,myavg FROM emp,(SELECT deptno,AVG(sal) myavg FROM emp GROUP BY deptno) tmp WHERE emp.deptno = tmp.deptno AND emp.sal > tmp.myavg) t1;
SELECT * FROM dept,(SELECT ename,emp.deptno,sal,myavg FROM emp,(SELECT deptno,AVG(sal) myavg FROM emp GROUP BY deptno) tmp WHERE emp.deptno = tmp.deptno AND emp.sal > tmp.myavg) t1 WHERE dept.deptno = t1.deptno;
SELECT t1.ename,dept.loc,t1.deptno FROM dept,(SELECT ename,emp.deptno,sal,myavg FROM emp,(SELECT deptno,AVG(sal) myavg FROM emp GROUP BY deptno) tmp WHERE emp.deptno = tmp.deptno AND emp.sal > tmp.myavg) t1 WHERE dept.deptno = t1.deptno;
-- 查找每个部门工资最高的人的姓名、工资、部门、最高工资
SELECT MAX(sal) FROM emp GROUP BY deptno;
SELECT deptno,MAX(sal) FROM emp GROUP BY deptno;
SELECT * FROM emp t1,(SELECT deptno,MAX(sal) FROM emp GROUP BY deptno) t2;
SELECT * FROM emp t1,(SELECT deptno,MAX(sal) FROM emp GROUP BY deptno) t2 WHERE t1.deptno = t2.deptno;
SELECT * FROM emp t1,(SELECT deptno,MAX(sal) mymax FROM emp GROUP BY deptno) t2 WHERE t1.deptno = t2.deptno AND t1.sal = t2.mymax;
SELECT t1.ename,t1.sal,t1.deptno,t2.mymax FROM emp t1,(SELECT deptno,MAX(sal) mymax FROM emp GROUP BY deptno) t2 WHERE t1.deptno = t2.deptno AND t1.sal = t2.mymax;
-- 显示每个部门的信息和人员数量
SELECT COUNT(*) FROM emp GROUP BY deptno;
SELECT deptno,COUNT(*) FROM emp GROUP BY deptno;
SELECT * FROM dept t1,(SELECT deptno,COUNT(*) FROM emp GROUP BY deptno) t2;
SELECT * FROM dept t1,(SELECT deptno,COUNT(*) FROM emp GROUP BY deptno) t2 WHERE t1.deptno = t2.deptno;

五、合并查询

在实际应用中,为了合并多个SELECT执行结果,可以使用操作符UNION、UNION ALL,两者的区别为:

1.UNION用于取得两个结果集的并集,会自动去掉结果集中的重复行;

2.UNION ALL用于取得两个结果集的并集,不会去掉结果集中的重复行;

sql 复制代码
-- 合并查询
-- 将工资大于2500或职位是MANAGER的人找出来
SELECT * FROM emp WHERE sal > 2500;
SELECT * FROM emp WHERE job = 'MANAGER';
SELECT * FROM emp WHERE sal > 2500 UNION SELECT * FROM emp WHERE job = 'MANAGER';
SELECT * FROM emp WHERE sal > 2500 UNION ALL SELECT * FROM emp WHERE job = 'MANAGER';
相关推荐
九零HTTP17 分钟前
10月21号-CSDN配菜-IP池的5个坑
服务器·数据库·tcp/ip
Data-Miner30 分钟前
需要做财务数据分析,有什么好用的工具?从准备到出报告的实操指南
大数据·数据库·数据分析
袋鼠云数栈1 小时前
让 SQL 解析不再重复造轮子:SqlParserX 正式开源
数据库·人工智能·sql·开源·数据治理
这个DBA有点耶2 小时前
期货 CTP 系统 Oracle RAC 迁移国产库实战:读写分离架构设计与性能对标
数据库·架构·dba
数据库安全2 小时前
AI数据访问安全 |如何控制AI访问权限,防止越权
数据库·安全
小羊没烦恼!2 小时前
异步编程:线程概述及使用
java·开发语言·mysql·算法·c#
这个DBA有点耶2 小时前
Redo Log循环写与checkpoint推进:长事务阻塞下的Checkpoint风暴完整链路
数据库·mysql·代码规范
jnrjian3 小时前
pg_waldump --key-file-name status 查看wal 产生的db
数据库
SelectDB技术团队3 小时前
Snowflake 的开源替代怎么选:能力对照、三条部署路径与迁移执行
大数据·数据库·云原生·开源·snowflake·apache doris
Elastic 中国社区官方博客3 小时前
告别繁琐控制台:Kabanos 如何将 MongoDB Compass 的易用性带入 Elasticsearch
大数据·数据库·mongodb·elasticsearch·搜索引擎·全文检索