子查询(第四天)

在这里插入图片描述
/*
子查询:
子查询要写在()中。子查询优先于主查询执行
单行子查询:
子查询只返回一行一列的值。单行子查询只和单行比较运算符一起使用
单行比较运算符:> >= < <= = <>
注意:
1.子查询要用括号括起来
2.子查询要写在比较运算符的右边
*/
在这里插入图片描述
– 查询工资比JONES工资高的员工信息

SELECT *
from emp
where sal> (
	select sal
	from emp
  where ename='JONES'
)

– 查询入职日期小于KING的入职日期的所有员工信息

SELECT *
from emp
where hiredate < (
	select hiredate
	from emp
	where ename='KING'
)

– 查询工资最低的员工的姓名,工资

SELECT ename,sal
from emp 
where sal = (
	select min(sal)
	from emp
)

– 查询比所有员工平均工资高的,并且奖金不为空的员工信息

SELECT  *
from  emp
where sal > (
	select avg(sal)
  from  emp
)  and comm is not null

– 查询20号部门的,工资比20号部门最高工资低的,入职日期比SMITH晚的员工信息

select *
from  emp
where deptno=20 and sal < (
	select max(sal)
  from  emp
  where deptno=20
) and hiredate > (
	select hiredate
  from  emp 
  where ename='SMITH'
)

– 查询部门最低工资比20部门最低工资高的部门编号及最低工资

SELECT deptno,min(sal)
from  emp
group by deptno
having min(sal) > (
	select min(sal)
  from  emp
  where deptno=20
)

注意:
在这里插入图片描述
–1.查询入职日期最早的员工姓名,入职日期

SELECT ename,hiredate
FROM emp
WHERE hiredate=(SELECT MIN(hiredate)FROM emp)

–2.查询工资比SMITH工资高并且工作地点在CHICAGO的员工姓名,工资,部门名称

SELECT ename,sal,e.deptno
FROM emp e,dept d
WHERE  sal>(
	SELECT sal
	FROM emp
	WHERE ename='smith'
)AND e.deptno=d.deptno AND loc='chicago'

– 3.查询入职日期比20部门入职日期最早的员工还要早的员工姓名,入职日期

SELECT ename,hiredate
FROM emp
WHERE hiredate < (
  SELECT MIN(hiredate)
  FROM emp
  WHERE deptno = 20
)

– 4 查询部门人数大于所有部门平均人数的的部门编号,部门名称,部门人数

select  count(e.ename),e.deptno,d.dname
from emp e,dept d
where e.deptno=d.deptno
GROUP BY deptno
having count(ename)> (
  SELECT  avg(aa.c)
from (select count(ename) c
  from  emp
  group by deptno) aa
)

– 子查询可以写在 where having from子句中
使用:
– 查询工资是所在部门最高工资的员工姓名,工资

select e.ename,e.sal,e.deptno
from  emp e, (
	select max(sal) msal,deptno
  from  emp
  group by deptno
) d
where  e.deptno=d.deptno and e.sal= d.msal

/*
**多行子查询:**子查询得到多个数据
多行子查询和多行操作符一起使用
多行操作符:IN ANY ALL
*/
In使用:
IN操作符和以前介绍的功能一致,判断是否与子查询的任意一个返回值相同。
In使用:
– 查询是经理的员工姓名,工资

select ename,sal
from  emp
where empno in  (
	select  distinct mgr
  from  emp
)

/*
ANY的使用:
ANY:表示和子查询的任意一行结果进行比较,有一个满足条件即可。

ANY: 比子查询中任意一个结果大即可。大于最小值
<any: 比子查询中任意一个结果小即可。小于最大值
=any: 相当于in, 表示等于子查询结果中的任意一个,即等于谁都可以
*/
ANY的使用:
– 查询30号部门的,比20号部门任意一个员工工资高的员工的姓名,工资

SELECT  ename,sal
from  emp
where deptno=30 and sal > any(
	SELECT sal
  from  emp
  where deptno=20
)

– 查询30号部门的,比20号部门任意一个员工工资低的员工的姓名,工资

SELECT  ename,sal
from  emp
where deptno=30 and sal < any(
	SELECT sal
  from  emp
  where deptno=20
)

/*
ALL的使用:
ALL:表示和子查询的所有行结果进行比较,每一行必须都满足条件。
<ALL: 小于子查询中所有行。小于最小值

all:大于子查询中所有行。大于最大值
=all: 不存在, 表示等于子查询结果集中的所有行,即等于所有值,通常无意义
*/

ALL的使用:
– 查询30号部门的,比20号部门所有员工工资低的员工的姓名,工资
SELECT ename,sal

from  emp
where deptno=30 and sal < all(
	SELECT sal
  from  emp
  where deptno=20
)

– 查询不是经理的员工姓名

select ename,sal
from  emp
where empno not in  (
	select  distinct IFNULL(mgr,0)
  from  emp
)

–查询部门编号不为20,且工资比20部门所有员工工资高的员工编号,姓名,职位,工资。

SELECT empno, ename,job, sal
FROM 	emp
WHERE 	sal > ALL (SELECT sal
                   FROM   emp
                   WHERE  deptno= 20)
AND    deptno <> 20;

子查询中的空值:
–查询不是经理的员工姓名
在这里插入图片描述
子查询返回的结果中含有空值
上面的SQL语句试图查找出没有下属的雇员,逻辑上,这个SQL语句应该会返回8条记录,但是却一条也没返回,why?
因为子查询的结果中有一条空值,这条空值导致主查询没有记录返回。这是因为所有的条件和空值比较结果都是空值。因此无论什么时候只要空值有可能成为子查询结果集合中的一部分,就不能使用NOT IN 运算符.

在 FROM 子句中使用子查询
–查询比自己部门平均工资高的员工姓名,工资,部门编号,部门平均工资
在这里插入图片描述
练习题:
– 1.查询部门平均工资在2500元以上的部门名称及平均工资

SELECT  avg(sal),dname
from  emp e,dept d
where e.deptno=d.deptno
group by e.deptno
having avg(sal)>2500

– 2.查询员工岗位中不是以“SA”开头并且平均工资在2500元以上的岗位及平均工资,并按平均工资降序排序。

SELECT JOB,AVG(SAL) AVGSAL
from  emp
where job not like 'SA%'
GROUP BY job
HAVING AVG(SAL)>2500
ORDER BY AVGSAL desc

– 3.查询部门人数在2人以上的部门名称、最低工资、最高工资,并对求得的工资进行四舍五入到整数位。

select d.dname,ROUND(max(sal)),ROUND(min(sal))
from  emp e,dept d
where e.deptno=d.deptno
group by e.deptno
having count(*)>2

– 4.查询岗位不为SALESMAN,工资和大于等于2500的岗位及每种岗位的工资和。

SELECT sum(sal),job
from emp
where job <> 'SALESMAN'
group by job
having sum(sal)>=2500

– 5.显示经理号码和经理姓名,这个经理所管理员工的最低工资,没有经理的KING也要显示,不包括最低工资小于3000的,按最低工资由高到低排序

SELECT min(e1.sal) msal,e2.empno,e2.ename
from emp e1 LEFT OUTER JOIN emp e2
 on e1.mgr = e2.empno
group by e2.empno
having min(e1.sal)>=3000
order by msal desc

– 6 查询工资高于编号为7782的员工工资,并且和7369号员工从事相同工作的员工的编号、姓名及工资

select empno,ename,sal
from emp
where sal>(
select sal from emp where empno=7782
	) and job=(select job from  emp where empno=7369)

– 7.查询工资最高的员工姓名和工资

SELECT ename,sal
from emp
where sal = (
SELECT max(sal) from emp
)

– 8. 查询部门最低工资高于10号部门最低工资的部门的编号、名称及部门最低工资

SELECT e.deptno,d.dname,min(sal)
from  emp e,dept d
where e.deptno=d.deptno
group by e.deptno
having min(sal)>(
SELECT min(sal)  from  emp  where deptno=10
)

– 9. 查询员工工资为其部门最低工资的员工的编号和姓名及工资

SELECT e.empno,e.ename,e.sal
from emp e,(
select deptno,min(sal) msal from emp group by deptno
) d
where e.deptno=d.deptno and e.sal= d.msal

– 10. 显示经理是KING的员工姓名,工资

SELECT ename,sal
from emp
where mgr=( select empno from  emp  where ename='KING' )

– 11. 显示比员工SMITH参加工作时间晚的员工姓名,工资,参加工作时间

SELECT  ename,sal,hiredate
from emp
where hiredate > (select hiredate from  emp  where ename='SMITH')

– 12. 使用子查询的方式查询哪些职员在NEW YORK工作

select *
from  emp
where deptno=(select deptno from  dept where loc='NEW YORK')

– 13. 写一个查询显示和员工SMITH工作在同一个部门的员工姓名,雇用日期,查询结果中排除SMITH

select ename,hiredate
from  emp 
where deptno=(select deptno from  emp where ename='SMITH')
 and ename <> 'SMITH'

– 14. 写一个查询显示其工资比全体职员平均工资高的员工编号、姓名

SELECT empno,ename
from emp
where sal>(select avg(sal) from emp)

– 15. 显示部门名称和人数

select d.dname,count(e.ename)
from emp e,dept d
where e.deptno=d.deptno
group by e.deptno

– 16. 显示每个部门的最高工资的员工

select e.ename,e.sal
from  emp e,(select max(sal) msal,deptno from  emp group by deptno) d
where e.deptno=d.deptno and e.sal=d.msal

– 17. 显示出和员工号7369部门相同的员工姓名,工资

SELECT ename,sal
from  emp
where deptno=(select deptno from emp where empno=7369)

– 18. 显示出和姓名中包含“W”的员工相同部门的员工姓名

SELECT ename
from emp
where deptno in (select deptno from emp where ename like '%W%')

猜你喜欢

转载自blog.csdn.net/gcyqweasd/article/details/112691389