--子查询 --子查询也是一条查询语句,只是它嵌套在其他sql语句中 --作用是为外层的sql提供数据 --查看比CLARK工资高的员工 select ename sal from emp_coco where sal>(select sal from emp_coco where ename='SMITH') SELECT * FROM EMP_COCO --和SMITH部门相同的员工 select ename,JOB from emp_coco where job=(select job from emp_coco where ename='SMITH') --查看比公司平均工资高的员工 select ename,sal from emp_coco where sal>(select avg(sal) from emp_coco) --DDL中使用子查询 --基于一个子查询的结果集快速创建一张表 create table emp_cococo as select e.empno,e.ename,e.job,e.deptno,d.dname,d.loc from emp_coco e,dept_coco d where e.deptno=d.deptno(+) DROP TABLE EMP_COCOCO select * from emp_coco --DML使用子查询 --将SMITH 部门所有员工工资提高%10: update emp_coco set sal=sal*1.1 where deptno=(select deptno from emp_coco where ename='SMITH') --查看与职位是SALESMAN相同部门的.其他.职位员工? select ename,job,deptno from emp_coco where deptno in (select deptno from emp_coco where job='SALESMAN')AND job<>'SALESMAN' --查看比职位时CLERK 和 SALESMAN工资都高的员工,可用all或 max select ename,sal from emp_coco where sal>ALL((select sal from emp_coco where job IN('CLERK','SALESMAN'))) --EXISTS关键字 --EXISTS后面要跟一个子查询,当该子查询可以至少查询出一条记录时 --EXISTS返回真,NOT EXISTS这是相反的操作 select deptno,dname from dept_coco d where exists ( select * from emp_coco e where d.deptno=e.deptno) --HAVING中使用子查询 --查看最低薪水高于30号部门最低薪水的部门 select deptno,min(sal) from emp_coco group by deptno having min(sal)>(select min(sal) from emp_coco where deptno=30) --单列作为条件 --多列子查询常被当作一张表看待而出现在FROM子句中 --查看高于自己部门平均工资的员工 --select avg(sal),deptno --不指名 报错 --from emp_coco --group by deptno (当作一张表看待) --子查询中的字段若是函数或者表达式那么必须给别名 select ename,sal,e.deptno from emp_coco e,(select avg(sal) avg_sal,deptno --指定别名 from emp_coco group by deptno) t where e.deptno=t.deptno and e.sal>t.avg_sal --SELECT 子句中也可以使用子查询 select e.ename,e.sal, (select d.dname from dept_coco d where d.deptno=e.deptno) dname from emp_coco e --显示null select e.ename,d.dname from dept_coco d,emp_coco e where d.deptno=e.deptno--不显示null select e.ename,d.dname from emp_coco e left outer join dept_coco d on e.deptno=d.deptno --分页查询 --分页查询是将查询的数据分段显示,这样做的目的可以减少资源占用,提高响应速度 --分页再不同的数据库中的 SQL语句是不一样的(方言) --ORACLE 中的分页是依靠伪列:ROWNUM实现的 --ROWNUM不存在与任何表中,但是任何表都可以查询该列,该列的值是随着查询数据的过程中生成的 --只要可以从查询出一条记录,那么 ROWNUM字段的值就是该记录的行号,从1开始 divlebo --在使用ROWNUM 对结果集进行编号的过程中不要使用rownum做>1以上的过滤判断, --否则结果集将得不到任何结果 select * from( select rownum r,ename,sal,deptno from emp_coco) where r between 6and 10 --由于排序在查询语句中的执行顺序是最低的,所以,在分页中若有排序需求时 --应当先排序,然后再根据排序的结果进行分页查询 select * from( select rownum r,t.* from( select ename,sal from emp_coco order by sal desc) t where rownum<=10)--加上次句效率高,不写r,因为where 比select先执行 where r between 6 and 10--若不写r,会默认为最外层 --根据页数以及每页显示的条目数来求范围的公式: --pageSize:5 每页显示的条目数 --page:1 页数 start=(page-1)*pageSize+1 end=pageSize*page --DECODE函数 --decode函数可以实现分支的效果 select ename,sal,job, decode(job, 'MANAGER',sal*1.2, 'ANALYST',SAL*1.1, 'SALESMAN',SAL*1.05, SAL)bonus from emp_coco --和decode 功能相似的有case语句 类似与if else的操作 select ename,job,sal, case job when 'MANAGER' THEN SAL*1.2 WHEN 'ANALYST' THEN SAL*1.1 WHEN 'SALESMAN' THEN SAL*1.05 ELSE SAL END bonus from emp_coco --可以利用DECODE将字段值不一样的记录看做同一组, --只需要将看做一组的记录该字段值替换为一个相同值即可 select count(*),decode(job, 'MANAGER','VIP', 'ANALYST','VIP', 'OTHER') D from emp_coco group by decode(job, 'MANAGER','VIP', 'ANALYST','VIP', 'OTHER') select deptno,dname,loc from dept_coco order by decode(dname, 'OPERATIONS',1, 'ACCOUNTING',2, 'ASLES',3)--没写的为null 最大 --排序函数 --排序函数允许对结果集按照给定的字段分组,然后在组内按照指定的字段排序 --然后生成一个组内编号 select ename,sal,deptno, row_number() over( partition by deptno order by sal desc )rank from emp_coco --RANK:生成组内不连续且不唯一的数字 select ename,sal,deptno, rank() over( partition by deptno order by sal desc )rank from emp_coco --DENSE_RANK:生成组内连续但不唯一的数字 select ename,sal,deptno, dense_rank() over( partition by deptno order by sal desc )rank from emp_coco --UNION select ename,job,sal from emp_coco where job='MANAGER' union all select ename,job,sal from emp_coco where sal>=2500 --INTERSECT 交集 select ename,job,sal from emp_coco where job='MANAGER' intersect select ename,job,sal from emp_coco where sal>=2500 --MINUS 差集 上面有,下没有,也就是结果集1减去结果集2的结果 --职位是MANAGER 但薪水低于2500的员工记录 select ename,job,sal from emp_coco where job='MANAGER' minus select ename,job,sal from emp_coco where sal>=2500 --高级分组函数 --高级分组函数可以按照该函数要求的分组方式对数据进行分组统计, --然后将这些方式统计的结果并到一个结果集中显示 --相比我们按照不同分组方式分别统计结果后再使用UNION ALL并在一起,书写起来要简便的多 create table sales_coco( year_id number not null, month_id number not null, day_id number not null, sales_value number(10,2) not null ) --插入1000条数据 insert into sales_coco select trunc(dbms_random.value(2010,2012))as year_id, trunc(dbms_random.value(1,13))as month_id, trunc(dbms_random.value(1,32))as day_id, round(dbms_random.value(1,100),2)as sales_value from dual connect by level<=1000 select * from sales_coco --ROLLUP select year_id,month_id,day_id,sum(sales_value) from sales_coco group by rollup(year_id,month_id,day_id) order by year_id,month_id,day_id --CUBE(a,b,c) 全方位统计 select year_id,month_id,day_id,sum(sales_value) from sales_coco group by cube(year_id,month_id,day_id) order by year_id,month_id,day_id --GROUPING SETS() --每个参数是一种分组方式,然后将这些分组统计的结果并在一个结果集显示 --由于分组方式可以通过参数传入,所以相比ROLLUP,CUBE的内定分组方式要灵活 select year_id,month_id,day_id,sum(sales_value) from sales_coco group by grouping sets( (year_id,month_id), (year_id,month_id,day_id)) order by year_id,month_id,day_id