数据库介绍4

子查询
在一条SQL语句中嵌套了SELECT查询语句


//查询最高薪水是谁?
  分步查询:
  //查询最高薪水值
  select max(salary) from emp_xu;//99999.99
  //根据最高薪水值找到对应的员工
  select ename,salary from emp_xu 
  where salary=99999.99;
  
  合并:
  select ename,salary from emp_xu 
  where salary=(
  select max(salary) from emp_xu
  );


非关联子查询
1)查询最高薪水是谁
  select ename,salary from emp_xu 
  where salary=(
  select max(salary) from emp_xu
  );


非关联子查询执行过程:先执行子查询,子查询返回
的结果作为主查询的条件,再执行主查询。
子查询只执行一次,若子查询返回结果为多个值,
oracle会去掉重复值,将结果返回给主查询。
特征:子查询是单独的查询语句,不依赖主查询的


2)查询最低薪水是谁
  分步查询:
  //查询最低薪水值
  select min(salary) from emp_xu;
  //根据最低薪水值找对应员工
  select ename,salary from emp_xu
  where salary=最低薪水值;
  
  合并:
  select ename,salary from emp_xu
  where salary=(
  select min(salary) from emp_xu
  );


3)谁的薪水比'张无忌'高
   分步查询:
   //查询'张无忌'薪水
   select salary from emp_xu 
   where ename='张无忌';
   
   //薪水大于'张无忌'薪水
   select  ename,salary from emp_xu
   where salary>'张无忌'薪水;
   
   合并:
   select  ename,salary from emp_xu
   where salary>(
   select salary from emp_xu 
   where ename='张无忌'
   );
   
4)查询研发部有哪些职位   
   分步查询:
   //找'研发部'对应的部门号
   select deptno from dept_xu 
   where dname='研发部';
   //根据部门号找对应的职位
   select deptno,position from emp_xu
   where deptno='研发部'部门号;
   
   合并:
   select deptno,position from emp_xu
   where deptno=(
   select deptno from dept_xu 
   where dname='研发部'
   );
   
5)谁的薪水比'张无忌'高(如果有多个'张无忌')
插入一条记录:
insert into emp_xu values(1014,'张无忌','Clerk',
8000,600,sysdate,1013,null);//全部字段


commit;


   select  ename,salary from emp_xu
   where salary>(
   select salary from emp_xu 
   where ename='张无忌'
   );//错误的,子查询返回多个值,不能直接用'>'


   修改:方式一
   select  ename,salary from emp_xu
   where salary>(
   select max(salary) from emp_xu 
   where ename='张无忌'
   );


   修改:方式二
   select  ename,salary from emp_xu
   where salary>all(
   select salary from emp_xu 
   where ename='张无忌'
   );


6)查询哪些人的薪水比'张无忌'高
  //比任意一个'张无忌'高即满足题目要求
   //查询最低薪水的'张无忌'
   select min(salary) from emp_xu 
   where ename='张无忌';
   //查询薪水大于最低薪水'张无忌'
   select ename,salary from emp_xu
   where salary>最低薪水'张无忌';
   
   合并:
   select ename,salary from emp_xu
   where salary>(
   select min(salary) from emp_xu 
   where ename='张无忌'
   );
   
   select ename,salary from emp_xu
   where salary>any(
   select salary from emp_xu 
   where ename='张无忌'
   );//子查询返回多值,大于任意一个即可,直接用
   >any来表示
   
7)谁和'郭靖'同部门,列出除了郭靖以外的名字(单值)   
  分步查询:
  //查询'郭靖'部门号
  select deptno from emp_xu
  where ename='郭靖';
  
  //根据部门号找对应的员工
  select deptno,ename from emp_xu
  where deptno='郭靖'部门号 and
  ename <>'郭靖';
  
  合并:  
  select deptno,ename from emp_xu
  where deptno=(
  select deptno from emp_xu
  where ename='郭靖'
  ) and ename <>'郭靖'; 
   
8)谁和'郭靖'同部门,列出除了郭靖以外的名字(多值)      
  select deptno,ename from emp_xu
  where deptno=any(
  select deptno from emp_xu
  where ename='郭靖'
  ) and ename <>'郭靖'; 
   
  select deptno,ename from emp_xu
  where deptno in(
  select deptno from emp_xu
  where ename='郭靖'
  ) and ename <>'郭靖';//=any可以直接用in来代替


9)谁是'张三丰'的下属(单值)
  分步查询:
  //查询'张三丰'员工号
  select empno from emp_xu
  where ename='张三丰';
  //谁的leader字段等于'张三丰'员工号
  select ename from emp_xu
  where leader='张三丰'员工号;
  
  合并:
  select ename,leader from emp_xu
  where leader=(
  select empno from emp_xu
  where ename='张三丰'
  );
  
  多值:
  select ename,leader from emp_xu
  where leader=any(
  select empno from emp_xu
  where ename='张三丰'
  );
  
  select ename,leader from emp_xu
  where leader in(
  select empno from emp_xu
  where ename='张三丰'
  );


总结:
根据子查询返回结果的行数选择比较运算符:
返回一行(单值):> >= < <= =
返回多行(多值):>all >any in 


10)查询每个部门拿最高薪水的是谁
 分步查询:
 //每个部门最高薪
 select deptno,max(salary)
 from emp_xu
 where deptno is not null
 group by deptno;
 
 //根据部门号和最高薪找对应的员工
 select ename,deptno,salary 
 from emp_xu
 where (deptno,salary) in 每个部门最高薪水;
 
 合并:
 select ename,deptno,salary 
 from emp_xu
 where (deptno,salary) in (
 select deptno,max(salary)
 from emp_xu
 where deptno is not null
 group by deptno
 );//子查询返回的是多值多列
 
 注意:子查询返回的结果是单列还是多列,主查询
 不关心,主查询只关心子查询返回的是单值还是多值
 问题。关键是能分清楚子查询返回的行数,决定使用
 合适运算符。
 
11)哪个部门的人数比部门30号的人数多
  分步查询:
  //30号部门人数
  select count(*) from emp_xu where deptno=30;
  
  //每个部门人数,要求大于30号部门人数
  select deptno,count(*)
  from emp_xu
  where deptno is not null
  group by deptno
  having count(*)>部门30号的人数;
  
  合并:
  select deptno,count(*)
  from emp_xu
  where deptno is not null
  group by deptno
  having count(*)>(
  select count(*) from emp_xu where deptno=30
  );//子查询出现having语句中的


12)哪个部门的平均薪水比部门20号的平均薪水高,没有
部门的不算在内
  分步查询:
  //部门20号的平均薪水
  select avg(nvl(salary,0)) from emp_xu 
  where deptno=20;
  
  //每个部门平均薪水,要求薪水大于20号部门平均薪水
  select deptno,avg(nvl(salary,0)) from emp_xu
  where deptno is not null
  group by deptno
  having avg(nvl(salary,0))>部门20号平均薪水;
  
  合并:
  select deptno,avg(nvl(salary,0)) from emp_xu
  where deptno is not null
  group by deptno
  having avg(nvl(salary,0))>(
  select avg(nvl(salary,0)) from emp_xu 
  where deptno=20
  );


13)查询员工所在部门平均薪水大于5000的员工姓名
和职位
 分步查询:
 //查询平均薪水大于5000的部门号
 select deptno from emp_xu
 where deptno is not null
 group by deptno
 having avg(nvl(salary,0))>5000;//多值
 
 //根据部门号找对应的员工姓名和职位
 select ename,position
 from emp_xu
 where deptno in 平均薪水大于5000的部门号;
 
 合并:
 select ename,position,deptno
 from emp_xu
 where deptno in (
 select deptno from emp_xu
 where deptno is not null
 group by deptno
 having avg(nvl(salary,0))>5000
 );


14)哪些员工的薪水是本部门的平均薪水值
 分步查询:
 //每个部门的平均薪水
 select deptno,avg(nvl(salary,0))
 from emp_xu
 where deptno is not null
 group by deptno;//多值多列
 
 //根据部门号和平均薪水找对应的员工信息
 select deptno,ename,salary
 from emp_xu
 where (deptno,salary) in (每个部门的平均薪水);
 
 合并:
 select deptno,ename,salary
 from emp_xu
 where (deptno,salary) in (
 select deptno,avg(nvl(salary,0))
 from emp_xu
 where deptno is not null
 group by deptno
 );






关联子查询
子查询不再是独立SQL语句,需要依赖主查询传过的
参数


1)哪些员工的薪水比本部门的平均薪水低
部门号相同,薪水小于平均薪水,两者的比较规则不
一样,不能直接用非关联子查询


select e.deptno,ename,salary
from emp_xu e
where salary<(
select avg(nvl(salary,0)) from emp_xu
where deptno is not null and deptno=e.deptno
);//子查询依赖主查询传递过来的参数e.deptno


关联子查询执行过程:
先执行主查询,把主查询的参数传给子查询,再执行
子查询,子查询返回的结果作为主查询的条件,再
执行主查询。子查询是执行多次的。子查询依赖主
查询的。


2)查询哪些人有下属
非关联子查询:
select ename from emp_xu
where empno=any(
select leader from emp_xu
);


select ename from emp_xu
where empno in(
select leader from emp_xu
);
关联子查询:exists关键字
exists判断存在某种关系:员工的员工号是别人的
leader字段,则表示该员工有下属


select ename from emp_xu e
where exists(
select 1 from emp_xu
where leader=e.empno
);


注意:exists关键字判断子查询有没有数据返回,有
则为true,没有则为false。exists不关心子查询返回
的结果,所以子查询中select后面写什么都可以。我
们一般直接用常量'1'表示。


3)查询哪些人没有下属
非关联子查询
select ename from emp_xu
where empno not in(
select leader from emp_xu
where leader is not null
);//not in表示判断不在列表项中,要求全部满足
即可,将列表项中空值情况去掉


注意:not in(列表项):如果列表中有空值,将没有
结果返回(未选定行);in(列表项):如果列表中有
空值对结果没有影响。


关联子查询:
select ename from emp_xu e
where not exists(
select 1 from emp_xu
where leader=e.empno
);


4)查询哪些部门有员工
非关联子查询:
select deptno,dname from dept_xu
where deptno in(
select distinct deptno from emp_xu
);


关联子查询:
select deptno,dname from dept_xu
where exists(
select 1 from emp_xu 
where deptno=dept_xu.deptno
);


5)查询哪些部门没有员工
insert into dept_xu values(50,'后勤部','广州');
commit;


非关联子查询:
select deptno,dname from dept_xu
where deptno not in(
select distinct deptno from emp_xu
where deptno is not null
);


关联子查询:
select deptno,dname from dept_xu
where not exists(
select 1 from emp_xu 
where deptno=dept_xu.deptno
);











猜你喜欢

转载自blog.csdn.net/little_____white/article/details/81053582