【Oracle】day04_子查询_分页查询_DECODE_排序_集合操作_高级分组
2015-09-16 23:54
771 查看
【Oracle】day04_子查询_分页查询_DECODE_排序_集合操作_高级分组
子查询可以嵌套在DQL,DML,DDL中使用
最常见的地方是在DQL当中使用.
SELECT ename,sal FROM emp
WHERE sal>(SELECT sal FROM emp WHERE ename='WARD');
SELECT ename,deptno FROM emp
WHERE deptno=(SELECT deptno FROM emp WHERE ename='JONES');
1)DDL中使用子查询
CREATE TABLE newemp_qxl
AS
SELECT e.ename,e.job,e.deptno,d.dname
FROM emp e JOIN dept d
ON e.deptno=d.deptno;
desc newemp_qxl;
SELECT * from newemp_qxl;
2)DML中使用子查询
DElETE FROM emp
WHERE deptno=(SELECT deptno FROM emp WHERE UPPER(ename)=('MILLER'));
update emp
set sal=sal*1.2
where deptno=(select deptno from emp where UPPER(ename)=('KING'));
select * from emp;
select ename,sal from emp
where sal>(select avg(sal) from emp);
SELECT ename,deptno,job FROM emp
WHERE deptno in(SELECT deptno from emp WHERE job='SALESMAN') AND job<>'SALESMAN';
SELECT ename,sal
FROM emp
WHERE sal>ANY(SELECT sal FROM emp WHERE deptno=20);
3)EXISTS关键字
用在WHERE子句中,其后要跟一个子查询,而EXISTS是否返回为TRUE取决于后面的子查询是否能查到数据.
在EXISTS前面还可以加上NOT.
SELECT d.deptno,d.dname FROM dept d
WHERE not exists(
select * from emp e where d.deptno=e.deptno
);
select min(sal),deptno
from emp
group by deptno
having min(sal)>(select min(sal) from emp where deptno=30);
4)多列子查询,通常当作一张表看待,定义在外层查询的FROM子句中使用.
--查询出薪水比本部门平均薪水高的员工信息
select e.ename,e.sal
from emp e,(SELECT deptno,AVG(sal) avg_sal FROM emp group by deptno) t
where e.sal>t.avg_sal
AND e.deptno=t.deptno;
在SELECT子句中也能使用子查询,是外连接的一种写法
子查询的结果必须是单行单列.
SELECT e.ename,e.sal,e.deptno,
(SELECT d.dname FROM dept d WHERE d.deptno=e.deptno) dname
FROM emp e;
1)ROWNUM:伪列,并不是表中的一个真实字段,但是在任何表的查询中都可以使用该列,该列的值为结果集每一条记录编一个行号,只要可以查询出一条记录该字段的值就会+1,行号从1开始.
SELECT ROWNUM,ename,sal FROM emp;
由于只有从表中查询出一条数据,ROWNUM才会使用1进行编号,然后其自动涨为2.所以,不要在第一次查询数据数据使用ROWNUM编号的时候在WHERE中做大于1以上的数字判断,否则不会查出任何数据.
select rownum,ename,sal from emp where rownum>1; --无任何数据被查出.
(ROENUM一开始不大于1,所以WHERE不满足条件,不满足WHERE条件就查询不出数据,查询不出数ROWNUM就不会涨,不涨就不大于1,所以WHERE不满足条件.....)
SELECT * FROM
(select ROWNUM rn,ename,sal,job,deptno
FROM emp) t
WHERE t.rn BETWEEN 6 AND 10;
2)分页的同时还有排序的需求时:
查看公司中工资排名的6-10位的员工信息?
由于使用ROWNUM编号是在查询的过程中完成的,而排序是在查询出数据之后进行的,所以这就导致排序后之前的编号就失去意义了.
下面并不会得到实际想要的数据.
SELECT * FROM(
SELECT ROWNUM rn,ename,sal,deptno
FROM emp
ORDER BY sal DESC
) t
WHERE t.rn BETWEEN 6 AND 10;
所以若有排序需求,分页需要三次查询才能实现:1-排序 2-编号 3-取范围
SELECT *
FROM(
SELECT ROWNUM rn,t.*
FROM(
SELECT ename,sal
FROM emp
ORDER BY sal DESC
) t
)
WHERE rn BETWEEN 6 AND 10;
分页时,BETWEEN中两个数字的公式:
page:页数
pagesize:每页显示的条数
根据上面两个值计算:
start:(page-1)*pagesize+1
end:page*pagesize
DECODE(
job,
'MANAGER',sal*1.2,
'SALESMAN',sal*1.1,
'ANALYST',sal*1.05,
sal
)bonus
FROM emp;
2)CASE语句
SELECT ename,sal,job,
CASE job WHEN 'MANAGER' THEN sal*1.2
WHEN 'SALESMAN'THEN sal*1.1
WHEN 'ANALYST'THEN sal*1.05
ELSE sal END
bonus
FROM emp;
3)GROUP BY 中使用DECODE函数
可以将字段值不同的记录看成一组,只要使用DECODE将需要划分一组的不同值转换为相同值即可.
SELECT COUNT(*) job_cnt,DECODE(job,'MANAGER','VIP','ANALYST','VIP',job) job_name
FROM emp
GROUP BY DECODE(job,'MANAGER','VIP','ANALYST','VIP',job);
4)ORDER BY 中使用DECODE
SELECT deptno,dname,loc
FROM dept
ORDER BY
DECODE(dname,
'OPERATIONS',1,
'ACCOUNTING',2);
4.排序
1)ROW_NUMBER函数,可以根据指定的字段分组,再根据指定的字段排序,然后生成组内连续且唯一的数字.
--查看每个部门的工资排名情况?
SELECT ename,sal,deptno,
ROW_NUMBER()
OVER(PARTITION BY deptno
ORDER BY sal DESC)rank
FROM emp;
2)RANK函数:生成组内不连续不唯一的数字
SELECT ename,sal,deptno,
RANK()
OVER(PARTITION BY deptno ORDER BY sal DESC)rank
FROM emp;
3)DENSE_RANK函数:生成组内连续但不唯一的数字
SELECT ename,sal,deptno,
DENSE_RANK()
OVER(PARTITION BY deptno ORDER BY sal DESC)rank
FROM emp_qxl;
SELECT ename,job,sal FROM emp
WHERE job='MANAGER'
UNION
SELECT ename,job,sal FROM emp
WHERE sal>2500;
2)INTERSECT 交集
SELECT ename,job,sal FROM emp
WHERE job='MANAGER'
INTERSECT
SELECT ename,job,sal FROM emp
WHERE sal>2500;
3)MINUS 差集
SELECT ename,job,sal FROM emp
WHERE job='MANAGER'
MINUS
SELECT ename,job,sal FROM emp
WHERE sal>4000;
1)ROLLUP 高级分组函数
ROLLUP函数用在GROUP BY子句中,ROLLUP函数中可以传入若干参数,作用是参数逐个递减,每次进行一回分组并统计结果,然后将这些结果并在一起显示.
SELECT year_id,month_id,day_id,SUM(sales_values) value
FROM sales_tab_qxl
GROUP BY ROLLUP(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id;
2)CUBE() 高级分组函数
会将给定的字段的每一种组合都进行一次分组,然后将所有结果并在一起显示.分组的次数是2的参数个数次方.
SELECT year_id,month_id,day_id,SUM(sales_values) value
FROM sales_tab_qxl
GROUP BY CUBE(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id;
3)GROUPING SETS 高级分组函数
可以按照给定的分组方式进行分组,然后结果并在一起显示.
每个参数表示一种分组方式,参数可以使用括号将要分组的字段组合起来表示一种.
SELECT year_id,month_id,day_id,SUM(sales_values)value
FROM sales_tab_qxl
GROUP BY GROUPING SETS(
(year_id,month_id,day_id),
(year_id,month_id)
)
ORDER BY year_id,month_id,day_id;
1.子查询
子查询的作用是为其他SQL语句提供数据,以便其他SQL可以根据该数据进行操作.子查询可以嵌套在DQL,DML,DDL中使用
最常见的地方是在DQL当中使用.
SELECT ename,sal FROM emp
WHERE sal>(SELECT sal FROM emp WHERE ename='WARD');
SELECT ename,deptno FROM emp
WHERE deptno=(SELECT deptno FROM emp WHERE ename='JONES');
1)DDL中使用子查询
CREATE TABLE newemp_qxl
AS
SELECT e.ename,e.job,e.deptno,d.dname
FROM emp e JOIN dept d
ON e.deptno=d.deptno;
desc newemp_qxl;
SELECT * from newemp_qxl;
2)DML中使用子查询
DElETE FROM emp
WHERE deptno=(SELECT deptno FROM emp WHERE UPPER(ename)=('MILLER'));
update emp
set sal=sal*1.2
where deptno=(select deptno from emp where UPPER(ename)=('KING'));
select * from emp;
select ename,sal from emp
where sal>(select avg(sal) from emp);
SELECT ename,deptno,job FROM emp
WHERE deptno in(SELECT deptno from emp WHERE job='SALESMAN') AND job<>'SALESMAN';
SELECT ename,sal
FROM emp
WHERE sal>ANY(SELECT sal FROM emp WHERE deptno=20);
3)EXISTS关键字
用在WHERE子句中,其后要跟一个子查询,而EXISTS是否返回为TRUE取决于后面的子查询是否能查到数据.
在EXISTS前面还可以加上NOT.
SELECT d.deptno,d.dname FROM dept d
WHERE not exists(
select * from emp e where d.deptno=e.deptno
);
select min(sal),deptno
from emp
group by deptno
having min(sal)>(select min(sal) from emp where deptno=30);
4)多列子查询,通常当作一张表看待,定义在外层查询的FROM子句中使用.
--查询出薪水比本部门平均薪水高的员工信息
select e.ename,e.sal
from emp e,(SELECT deptno,AVG(sal) avg_sal FROM emp group by deptno) t
where e.sal>t.avg_sal
AND e.deptno=t.deptno;
在SELECT子句中也能使用子查询,是外连接的一种写法
子查询的结果必须是单行单列.
SELECT e.ename,e.sal,e.deptno,
(SELECT d.dname FROM dept d WHERE d.deptno=e.deptno) dname
FROM emp e;
2.分页查询
分页的目的是,当数据量过大时,若一次性全部查询出来,会对系统资源造成不必要开销,而且处理速度会变慢,为此我们可以分段式的将数据一点一点的取出.分页的语句SQL没有定义,所以不同的数据库分页语句不一样.1)ROWNUM:伪列,并不是表中的一个真实字段,但是在任何表的查询中都可以使用该列,该列的值为结果集每一条记录编一个行号,只要可以查询出一条记录该字段的值就会+1,行号从1开始.
SELECT ROWNUM,ename,sal FROM emp;
由于只有从表中查询出一条数据,ROWNUM才会使用1进行编号,然后其自动涨为2.所以,不要在第一次查询数据数据使用ROWNUM编号的时候在WHERE中做大于1以上的数字判断,否则不会查出任何数据.
select rownum,ename,sal from emp where rownum>1; --无任何数据被查出.
(ROENUM一开始不大于1,所以WHERE不满足条件,不满足WHERE条件就查询不出数据,查询不出数ROWNUM就不会涨,不涨就不大于1,所以WHERE不满足条件.....)
SELECT * FROM
(select ROWNUM rn,ename,sal,job,deptno
FROM emp) t
WHERE t.rn BETWEEN 6 AND 10;
2)分页的同时还有排序的需求时:
查看公司中工资排名的6-10位的员工信息?
由于使用ROWNUM编号是在查询的过程中完成的,而排序是在查询出数据之后进行的,所以这就导致排序后之前的编号就失去意义了.
下面并不会得到实际想要的数据.
SELECT * FROM(
SELECT ROWNUM rn,ename,sal,deptno
FROM emp
ORDER BY sal DESC
) t
WHERE t.rn BETWEEN 6 AND 10;
所以若有排序需求,分页需要三次查询才能实现:1-排序 2-编号 3-取范围
SELECT *
FROM(
SELECT ROWNUM rn,t.*
FROM(
SELECT ename,sal
FROM emp
ORDER BY sal DESC
) t
)
WHERE rn BETWEEN 6 AND 10;
分页时,BETWEEN中两个数字的公式:
page:页数
pagesize:每页显示的条数
根据上面两个值计算:
start:(page-1)*pagesize+1
end:page*pagesize
3.DECODE函数
SELECT ename,sal,job,DECODE(
job,
'MANAGER',sal*1.2,
'SALESMAN',sal*1.1,
'ANALYST',sal*1.05,
sal
)bonus
FROM emp;
2)CASE语句
SELECT ename,sal,job,
CASE job WHEN 'MANAGER' THEN sal*1.2
WHEN 'SALESMAN'THEN sal*1.1
WHEN 'ANALYST'THEN sal*1.05
ELSE sal END
bonus
FROM emp;
3)GROUP BY 中使用DECODE函数
可以将字段值不同的记录看成一组,只要使用DECODE将需要划分一组的不同值转换为相同值即可.
SELECT COUNT(*) job_cnt,DECODE(job,'MANAGER','VIP','ANALYST','VIP',job) job_name
FROM emp
GROUP BY DECODE(job,'MANAGER','VIP','ANALYST','VIP',job);
4)ORDER BY 中使用DECODE
SELECT deptno,dname,loc
FROM dept
ORDER BY
DECODE(dname,
'OPERATIONS',1,
'ACCOUNTING',2);
4.排序
1)ROW_NUMBER函数,可以根据指定的字段分组,再根据指定的字段排序,然后生成组内连续且唯一的数字.--查看每个部门的工资排名情况?
SELECT ename,sal,deptno,
ROW_NUMBER()
OVER(PARTITION BY deptno
ORDER BY sal DESC)rank
FROM emp;
2)RANK函数:生成组内不连续不唯一的数字
SELECT ename,sal,deptno,
RANK()
OVER(PARTITION BY deptno ORDER BY sal DESC)rank
FROM emp;
3)DENSE_RANK函数:生成组内连续但不唯一的数字
SELECT ename,sal,deptno,
DENSE_RANK()
OVER(PARTITION BY deptno ORDER BY sal DESC)rank
FROM emp_qxl;
5.集合操作
1)UNION 并集SELECT ename,job,sal FROM emp
WHERE job='MANAGER'
UNION
SELECT ename,job,sal FROM emp
WHERE sal>2500;
2)INTERSECT 交集
SELECT ename,job,sal FROM emp
WHERE job='MANAGER'
INTERSECT
SELECT ename,job,sal FROM emp
WHERE sal>2500;
3)MINUS 差集
SELECT ename,job,sal FROM emp
WHERE job='MANAGER'
MINUS
SELECT ename,job,sal FROM emp
WHERE sal>4000;
6.高级分组
--准备数据 CREATE TABLE sales_tab_qxl( year_id NUMBER NOT NULL, month_id NUMBER NOT NULL, day_id NUMBER NOT NULL, sales_values NUMBER(10,2) NOT NULL ); DESC sales_tab_qxl; INSERT INTO sales_tab_qxl 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 dayr_id, ROUND(DBMS_RANDOM.value(1,100),2) AS sales_value FROM dual CONNECT BY level<=1000; select * from sales_tab_qxl; --查看每天的销售额? SELECT year_id,month_id,day_id,SUM(sales_values) value FROM sales_tab_qxl GROUP BY year_id,month_id,day_id ORDER BY year_id,month_id,day_id; --查看每月的销售额? SELECT year_id,month_id,SUM(sales_values) value FROM sales_tab_qxl GROUP BY year_id,month_id ORDER BY year_id,month_id; --查看每年的销售额? SELECT year_id,SUM(sales_values) value FROM sales_tab_qxl GROUP BY year_id ORDER BY year_id;
1)ROLLUP 高级分组函数
ROLLUP函数用在GROUP BY子句中,ROLLUP函数中可以传入若干参数,作用是参数逐个递减,每次进行一回分组并统计结果,然后将这些结果并在一起显示.
SELECT year_id,month_id,day_id,SUM(sales_values) value
FROM sales_tab_qxl
GROUP BY ROLLUP(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id;
2)CUBE() 高级分组函数
会将给定的字段的每一种组合都进行一次分组,然后将所有结果并在一起显示.分组的次数是2的参数个数次方.
SELECT year_id,month_id,day_id,SUM(sales_values) value
FROM sales_tab_qxl
GROUP BY CUBE(year_id,month_id,day_id)
ORDER BY year_id,month_id,day_id;
3)GROUPING SETS 高级分组函数
可以按照给定的分组方式进行分组,然后结果并在一起显示.
每个参数表示一种分组方式,参数可以使用括号将要分组的字段组合起来表示一种.
SELECT year_id,month_id,day_id,SUM(sales_values)value
FROM sales_tab_qxl
GROUP BY GROUPING SETS(
(year_id,month_id,day_id),
(year_id,month_id)
)
ORDER BY year_id,month_id,day_id;
相关文章推荐
- 【Oracle】day03_查询语句_聚合函数_关联查询
- hibernate3.4 注解 oracle简单入门例子
- oracle 同一个表出现2个用户创建的同名触发器
- oracle按照主键索引查询不到数据
- 安装与配置Oracle Warehouse Builder 11.2.0.3
- Oracle hang 之sqlplus -prelim方法
- oracle11G手动建库
- Oracle学习之常见问题处理
- Oracle 序列 触发器的使用
- 更改Oracle数据库的编码格式,解决导入时ORA-12899错误
- Oracle建立表空间、建立用户、用户授权、指定表空间、激活用户、删除用户、删除表空间
- Oracle主键、唯一键与唯一索引的区别
- Oracle环境下的Hibernate方言配置
- 利用ORACLE实现数据抽样(sample block)
- oracle数据库实例启动与关闭
- oracle 表空间不足处理
- Kettle 5.4 SQL2Oracle简单实例
- Oracle 学习笔记 18 -- 存储函数和存储过程(PL/SQL子程序)
- window、linux安装jdk,excel 导入oracle,WebService,window 端口查看,svn服务安装,oracle用户解锁
- Oracle临时表 和 插入多条语句 用法