因为分组函数是多行函数,在不主动分组的情况下,是只会有一行的数据
我们想要在SELECT子句中是拿分组字段的结果是不会对应匹配数据的,它会随机给你匹配一个数据
直接去WHERE子句中进行分组函数的筛选也是不可以的,要在GROUP BY子句之后才会存在分组(没写的话,默认有一个GROUP BY子句,是把所有数据行分为一组)
因此我们就引入了子查询的方式
在SELECT子句中,得到一个字段(一个子查询仅可以得到一个字段)
在FROM子句中,得到一个新表
在WHERE子句中,得到一个或多个值
把子查询得到的结果当作一个字段去进行匹配使用
在这个字段里面一定有WHERE语句
因为要保证每次返回的都是一个值,而不是多个值(单行值和多个值是无法进行匹配的,这是会报错的)
两个表不想要通过连接,但是又想要获取相对应的数据,可以在SELECT子句里面写子查询
查一个其他表的一个字段信息,就得写一个子查询语句
SELECT 别名1.表1独有字段,(子查询语句)
FROM 表1 别名1;
/*
表1一定要取别名,因为你会在SELECT子句中的子查询中使用它去进行筛选
子查询语句里面要实现别名1.共有字段=别名2.共有字段
其中别名2是子查询中需要查询的表
每个子查询仅能获取一个字段,效率太低了且可读性不高
*/
SELECT e.ename '员工姓名',(SELECT dname FROM dept d WHERE e.deptno=d.deptno) '部门名称',(SELECT loc FROM dept d WHERE e.deptno=d.deptno) '部门所在地'
FROM emp e;
/*通过SELECT子句的子查询获取员工姓名、员工的部门名称、员工的部门所在地*/
d1 第一个SELECT子句的子查询返回部门名称
d2 第二个SELECT子句的子查询返回部门所在地的值
d3 每次的ename会与前面得到的两个值进行对应匹配(子查询里面就进行对应匹配)
d4.每次把对应符合条件的数据行放入结果表中
d5 在mysql界面中进行结果表信息的展示
把子查询得到的结果当作一个新表
一般来说,是去与其他表进行连接(内连接、外连接)操作
若此时子查询里面有分组函数的话,那么就需要给它取上别名
SELECT 别名1.字段1...别名1.字段n,别名2.字段1...别名2.字段n
FROM (子查询语句) 别名1
连接关键字(LEFT/RIGHT/INNER) JOIN 表2 别名2
ON 别名1.共有字段=别名2.共有字段;
SELECT e.deptno '部门编号',e.a1 '平均薪水',s.grade '平均薪水对应的工资等级'
FROM
(
SELECT deptno,AVG(sal) a1
FROM emp
GROUP BY deptno
) e
LEFT JOIN salgrade s
ON e.a1 BETWEEN s.losal AND s.hisal;
/*求每个部门的部门编号、平均薪水、平均薪水对应的等级
写连接的时候一定要清楚哪个是主表哪个是副表,很显然工资等级表是副表
子查询里面涉及到分组函数,就需要给分组函数取上别名,这样方便获取其值
*/
d1 在FROM子句中的子查询得到含有每个部门编号和对应的平均薪水的值的一个新表
d2 拿新表和salgrade表进行左连接
d3 左连接后得到含有两个表的所有字段(这些字段是通过连接条件进行相对应的)的结果表
d4 根据SELECT 子句中字段去结果表中拿去相应的值即可
d5 在mysql界面中进行信息的展示
返回一个值,使其和字段发生比较运算
要求该值和字段应当是相同数据类型,不然比较了就没有啥意义了
SELECT
FROM 表1
WHERE 字段1 比较运算符 (子查询语句);
/*
子查询语句可以理解成一个正常的查询语句,这里是把查询的出的结果当成一个值去进行比较运算
它里面的书写和基本的查询书写语法是一致的
*/
SELECT ename '员工名字',sal '薪水'
FROM emp
WHERE sal >(SELECT avg(sal) FROM emp);
/*找出员工表中比所有员工平均薪水还高的员工的姓名以及薪水信息*/
d1 SELECT avg(sal) FROM emp这句话返回一个所有员工薪水平均值 a1
d2 然后逐行比较sal是否大于a1,若大于就放入该条数据行放入结果表中,否则就继续往下行进行判断
d3 比较完emp的所有数据行后就会进入SELECT 子句
d4 根据SELECT 子句中字段去结果表中拿去相应的值即可
d5 在mysql界面中进行信息的展示
返回多个值,通过谓词 in和WHERE子句筛选出想要的结果
SELECT
FROM
WHERE 字段1 in(子查询语句);
/*
我们之前提过,子查询的语句外面是需要加上括号的,
但是这里无需套上括号了,这个点是需要特别注意的
之前加上括号是让DBMS区分哪部分是SELECT子句,哪部分是FROM子句
你放入in谓词括号中后,就告知DBMS它在in谓词中了,此时就无需加上括号进行区分了
*/
SELECT ename '员工姓名',deptno '部门编号',sal '薪水'
FROM emp
WHERE sal in(SELECT MAX(sal) FROM emp GROUP BY deptno);
/*得到每个部门中最高工资的员工的姓名、部门编号、薪水
若该部门有多个员工的薪水都是最高薪水,那就都会显示出来
*/
d1 SELECT MAX(sal) FROM emp GROUP BY deptno得到每个部门里面的薪水的最大值
d2 sal使用in谓词(简化版的多重OR语句)可以匹配到多个符合条件的数据行
d3 然后把它们放入到结果表中
d4 通过SELECT 子句中需要查询的ename字段、deptno字段、sal字段获取到想要展示的结果
d5 在mysql界面中进行信息的展示