SQL查询语句之子查询1
【子查询】
1、 子查询的各个使用形式。
2、 分析子查询的主要意义。
实际上,对于整个的SQL语法而言,所有的组成,就是几个固定的查询语句:SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY。
而所谓的子查询,指的就是,在一个查询里面继续嵌套其他的查询语句。如果非要给子查询一个语法的话:
SELECT [ DISTINCT ] 分组字段 [别名],... | 统计函数, (
SELECT [ DISTINCT ] 分组字段 [别名],... | 统计函数
FROM 表名称 [别名],表名称 [别名],...
[ WHERE 过滤条件(s) ]
[ GROUP BY 分组字段,分组字段,... ]
[ HAVING 分组后的过滤条件 ]
[ ORDER BY 字段 [ ASC | DESC ],字段 [ ASC | DESC ],... ] )
FROM 表名称 [别名],表名称 [别名],... , (
SELECT [ DISTINCT ] 分组字段 [别名],... | 统计函数
FROM 表名称 [别名],表名称 [别名],...
[ WHERE 过滤条件(s) ]
[ GROUP BY 分组字段,分组字段,... ]
[ HAVING 分组后的过滤条件 ]
[ ORDER BY 字段 [ ASC | DESC ],字段 [ ASC | DESC ],... ] )
[ WHERE 过滤条件(s) (
SELECT [ DISTINCT ] 分组字段 [别名],... | 统计函数
FROM 表名称 [别名],表名称 [别名],...
[ WHERE 过滤条件(s) ]
[ GROUP BY 分组字段,分组字段,... ]
[ HAVING 分组后的过滤条件 ]
[ ORDER BY 字段 [ ASC | DESC ],字段 [ ASC | DESC ],... ] ) ]
[ GROUP BY 分组字段,分组字段,... ]
[ HAVING 分组后的过滤条件 (
SELECT [ DISTINCT ] 分组字段 [别名],... | 统计函数
FROM 表名称 [别名],表名称 [别名],...
[ WHERE 过滤条件(s) ]
[ GROUP BY 分组字段,分组字段,... ]
[ HAVING 分组后的过滤条件 ]
[ ORDER BY 字段 [ ASC | DESC ],字段 [ ASC | DESC ],... ] ) ]
[ ORDER BY 字段 [ ASC | DESC ],字段 [ ASC | DESC ],... ] ;
在一个查询语句之中,有可能会同时嵌套多个子查询。对于子查询的时候,给出几个非官方的使用方法:
◆ WHERE子句:子查询一般会返回单行单列、单行多列、多行单列数据。
◆ HAVING子句:子查询会返回单行单列,同时表示要使用统计函数。
◆ FROM子句:子查询返回多行多列数据(表结构)。
◆ SELECT子句:返回单行单列,不过一般不使用。
【在WHERE子句里面,使用子查询(重点)】
WHERE子句的作用是,进行数据行的筛选操作的。
范例:查询出低于公司 平均工资 的雇员信息
◆ 应该先统计出公司的平均工资的数值。
SELECT AVG(sal) FROM emp ;
◆ 以上的查询,返回单行单列,可以作为WHERE子句的过滤条件使用。
SELECT * FROM emp
WHERE sal<(SELECT AVG(sal) FROM emp ) ;
范例:查询出公司最早雇佣的雇员信息
◆ 使用MIN( )函数,找到最早的雇佣日期,返回单行单列数据。
SELECT MIN(hiredate) FROM emp ;
◆ 如果返回单行单列数据,并且又不使用统计函数,在WHERE子句中出现。
SELECT * FROM emp
WHERE hiredate=(SELECT MIN(hiredate) FROM emp ) ;
除了返回单行单列的内容之外,还可以返回单行多列,此类的操作,一般不会经常使用。
范例:查询与SCOTT从事同一工作,并且工资相同的雇员信息。
◆ 首先应该知道SCOTT的工作和工资。
SELECT job, sal FROM emp WHERE ename='SCOTT' ;
◆ 需要有另外的雇员在职位和工资上,与SCOTT的完全相同,由于此时返回的是单行多列的内容,所以需要使用( )进行描述。
SELECT * FROM emp
WHERE (job, sal)=(
SELECT job, sal FROM emp WHERE ename='SCOTT' )
AND ename<>'SCOTT' ;
如果说子查询返回的内容,是多行单列的话,那么,就表示: 一个操作的数据范围。所以,对于此类的判断,在SQL语句之中,提供有三个操作符:IN(应)、ANY(安你)、ALL噢。
1、 IN操作: 指的是与子查询返回的内容相同
查询经理们的工资
SELECT sal FROM emp WHERE job='MANAGER' ;
查询 工资 与经理们的工资 相同的 所有雇员信息
SELECT * FROM emp WHERE sal IN(
SELECT sal FROM emp WHERE job='MANAGER' ) ;
此过程,与之前所学的IN操作,完全相同,唯一的区别在于,之前学的IN的范围内容是自己设置的,而此时是通过子查询而来的。
那么,既然有了IN操作,就一定会有NOT IN操作。
查询工资与经理们的工资不同的所有雇员信息
SELECT * FROM emp
WHERE sal NOT IN(
SELECT sal FROM emp WHERE job='MANAGER' ) ;
SELECT * FROM emp
WHERE NOT sal IN(
SELECT sal FROM emp WHERE job='MANAGER' ) ;
但是,如果使用的是NOT IN或者是NOT ... IN,新的问题就出现了,子查询里面,不能够返回null。如果子查询返回了null,那么,最终的查询,不会有任何的结果出现。
范例:子查询返回了null
SELECT mgr FROM emp ;
SELECT * FROM emp WHERE empno NOT IN(
SELECT mgr FROM emp ) ;