您的位置:首页 > 数据库 > Oracle

Oracle 11g 第六章知识点总结——子查询

2012-09-09 18:30 796 查看
Oracle 11g 第六章知识点总结——子查询

知识点预览
 

子查询

子查询
 

1.      使用子查询解决问题

 

谁的工资比 Abel 高?

 

 


 

2.      子查询语法

a)        子查询 (内查询) 在主查询之前一次执行完成。

b)       子查询的结果被主查询使用 (外查询)。

 

SELECT select_list

FROM   table

WHERE expr operator

                    (SELECT      select_list

                     FROM           
table);


 

3.      子查询

 

SELECT last_name
FROM   employees
WHERE  salary >
(SELECT salary
FROM   employees
WHERE  last_name = 'Abel');


4.      注意事项

a)        子查询要包含在括号内。

b)       将子查询放在比较条件的右侧。

c)        除非进行Top-N 分析,否则不要在子查询中使用ORDERBY 子句。

d)       单行操作符对应单行子查询,多行操作符对应多行子查询。

5.      子查询类型


 

6.      单行子查询

a)        只返回一行。

b)       使用单行比较操作符。

 


 

 
7.      执行单行子查询

 

SELECTlast_name, job_id, salary
FROM   employees
WHERE  job_id =
(SELECT job_id
FROM   employees
WHERE  employee_id = 141)
AND    salary >
(SELECT salary
FROM   employees
WHERE  employee_id = 143);


8.      在子查询中使用组函数

 

SELECTlast_name, job_id, salary
FROM   employees
WHERE  salary =
(SELECT MIN(salary)
FROM   employees);


9.      子查询中的 HAVING 子句

a)        首先执行子查询。

b)       向主查询中的HAVING 子句返回结果。

 

SELECT   department_id,MIN(salary)
FROM     employees
GROUP BY department_id
HAVING   MIN(salary) >
(SELECTMIN(salary)
FROM   employees
WHERE  department_id = 50);


10.  非法使用子查询

 

SELECT employee_id,last_name
FROM   employees
WHERE  salary =
(SELECT   MIN(salary)
FROM     employees
GROUP BY department_id);


 



 
 
11.  子查询中的空值问题

 

SELECTlast_name, job_id
FROM   employees
WHERE  job_id =
(SELECT job_id
FROM   employees
WHERE  last_name = 'Haas');




12.  多行子查询

a)        返回多行。

b)       使用多行比较操作符。

 



 

13.  在多行子查询中使用 ANY 操作符

 

SELECTemployee_id, last_name, job_id, salary
FROM   employees
WHERE  salary < ANY
(SELECT salary
FROM   employees
WHERE  job_id = 'IT_PROG')
AND    job_id <> 'IT_PROG';


14.  在多行子查询中使用 ALL 操作符

 

SELECTemployee_id, last_name, job_id, salary
FROM   employees
WHERE  salary < ALL
(SELECT salary
FROM   employees
WHERE  job_id = 'IT_PROG')
AND    job_id <> 'IT_PROG';


15.  子查询中的空值问题

 

SELECTemp.last_name
FROM   employees emp
WHERE  emp.employee_id NOT IN/EXISTS
(SELECTmgr.manager_id
FROM   employees mgr);


 

no rows selected

16.  示例

 

--查询出比MARTIN工资高的所有人
--分析:
--a.查询出MARTIN的工资
selectsal from emp where ename = 'MARTIN';
--b.查询出比他高的所有人
selectename,sal
fromemp
wheresal >
--子查询要包含在括号内
(
select sal
from emp
where ename = 'MARTIN'
);

--<ALL --小于最小的
--<ANY --小于最大的
-->ALL --大于最大的
-->ANY --大于最小的
--=ANY --等价于in
--=ALL --报错
--多行子查询
--<any小于最大的 =any /  in
--<all  小于最小的
--1.       列出至少有一个员工的所有部门
select count(*) ,sum(sal),deptno
from emp
having count(*)>=1
group by deptno
--2.列出薪金比"SMITH"高的所有员工
--4.列出受雇日期早于其直接上级的所有员工的编号,姓名,部门名称。

select e.empno,e.ename,d.dname
from
emp e, emp m,
(
selectdeptno,dname
fromdept
) d
where e.hiredate < m.hiredate
and e.mgr = m.empno
andd.deptno = e.deptno;
--5.列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。

select d.dname,e.ename,e.deptno
from emp e right outer join dept d
on e.deptno = d.deptno;
--6.列出所有"CLERK"(办事员)的姓名及其部门名称,部门的人数
selectename,e.deptno,d.dname,t.num
fromemp e,dept d , (
selectdeptno,count(*) num
fromemp
wherejob='CLERK'
groupby deptno
)t
where job='CLERK' and e.deptno=d.deptno andd.deptno=t.deptno;

selecte.ename,d.dname,t.num
fromemp e, dept d,
(
select deptno,count(*) num
from emp
where job = 'CLERK'
group by deptno
)t
where e.deptno = d.deptno and job = 'CLERK'and t.deptno = e.deptno;
--7.列出最低薪金大于1500的各种工作及从事此工作的全部雇员人数

select job, count(*)
from emp
having min(sal) > 1500
group by job;

--8.列出在部门"SALES"(销售部)工作的员工的姓名,假定不知道销售部门的部门编号。

select deptno from dept where dname ='SALES';
select e.ename from emp;

select e.ename,e.deptno
from emp e
where e.deptno =
(
selectdeptno
fromdept where
dname= 'SALES'
);
--9.列出薪金高于公司平均薪金的所有员工,所在部门,上级领导,--工资等级。
selecte.ename,e.sal,d.dname,m.ename
fromemp e,dept d,emp m
wheree.sal>(
selectavg(sal) from emp
)and e.deptno=d.deptno and e.mgr=m.empno;

select e.ename,temp.dname,m.ename as "上级领导"
from
emp e, emp m,(
selectdeptno,dname
from
dept
) temp
where e.mgr = m.empno
and temp.deptno = e.deptno
and e.sal >
(select avg(sal)
from emp);
--10.列出与"SCOTT"从事相同工作的所有员工及部门名称
select e.ename,temp.dname
from emp e,
(
selectdeptno,dname
from
dept
)temp
where e.job =
(
selectjob
fromemp
whereename = 'SCOTT'
) and e.deptno = temp.deptno
and e.ename != 'SCOTT';

--11.列出薪金等于部门30中员工的薪金的所有员工的姓名和薪金

select e.ename, e.sal
from emp e
where
e.sal = any
(
selectsal
fromemp
wheredeptno = 30
);

--12.列出薪金高于在部门30工作的所有员工的薪金的员工的姓名和薪金、部门名称。

select e.ename, e.sal, temp.dname
from emp e,
(
selectdeptno,dname
from
dept
) temp
where
e.sal > all
(
selectsal
fromemp
wheredeptno = 30
) and temp.deptno = e.deptno;
--13.列出在每个部门工作的员工数量、平均工资和平均服务期限。

select count(*),avg(sal),avg(round((sysdate -hiredate) / 365, 0)),deptno
from emp
group by deptno;
--14.列出所有员工的姓名、部门名称和工资

select e.ename,temp.dname,e.sal
from emp e,
(
selectdeptno,dname
from
dept
) temp
where temp.deptno = e.deptno;
--15.列出所有部门的详细信息和部门人数
selectd.*,t.c
fromdept d,(
selectdeptno,count(*) c
fromemp
groupby deptno
)t
whered.deptno=t.deptno;

select d.*,temp.c
from dept d,
(
select count(*) asc,deptno
from emp
group by deptno
)temp
where d.deptno = temp.deptno;

--优化
select dept.dname,tem.num
from dept
left join
(select deptno, count(*) num
from emp
group by(deptno)
)tem
on tem.deptno = dept.deptno;

--16.列出各种工作的最低工资及从事此工作(从事该职位且工资最低)的雇员姓名。
--1列出各种工作的最低工资
selecte.ename,e.sal,t.s,t.job
fromemp e,(
selectmin(sal) s,job
fromemp
groupby job
)t
wheree.sal=t.s;

--17.出各个部门的MANAGER(经理)的最低薪金。

selectmin(sal)
fromemp
wherejob = 'MANAGER'
group by deptno;
--18.列出所有员工的年工资,按年薪从低到高排序。
selectsal*12 s from emp order by s;
selectename,sal * 12 as "年薪"
fromemp
orderby sal;

selectename,sal * 12 as "年薪"
fromemp
orderby sal * 12;

--19.查处某个员工的上级主管,并要求出这些主管的薪水超过3000

selecte.ename,e.mgr,m.empno,m.ename
fromemp e, emp m
wheree.mgr = m.empno
andm.sal > 3000;
--20.求出部门名称中,带‘S’字符的部门员工的工资合计、部门人数
selectd1.dname,t.*
fromdept d1,(
selectcount(*),sum(e.sal),e.deptno
fromemp e,dept d
whered.dname like '%S%' and e.deptno=d.deptno
groupby e.deptno
)t
whered1.deptno=t.deptno;

--第一行:ORA-00937: 不是单组分组函数
select sum(e.sal), temp.c
from emp e,
(
selectcount(*) c
fromdept
groupby deptno
)temp
where e.deptno
in
(
selectdeptno
fromdept
wheredname like '%S%'
);

select sum(sal), count(*)
from emp
group by deptno
having deptno
in
(
selectdeptno
fromdept
wheredname like '%S%'
);
--21.给任职日期超过10年的人加薪10%


 
第9题:


 

第15题:

 


第16题:

 


第20题:
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息