1、分页查询
Oracle分页关键字:rownum
MySql的分页关键字:limit
1)、rownum:伪列
该列在数据库表中并不存在,但是它又“存在于”
任何的表中。该字段的取值取决于查询语句的记录数。
rownum其实就是对查询出的记录数据做编号处理,
编号从1开始。
rownum存在的sql,必须是对真实字段名的查询。
--rownum不能直接跟*一起使用。
select *,rownum from emp;
--rownum正确使用
select empno,ename,hiredate,sal,deptno,rownum
from emp;
--查询rownum <= 终止位置
--查询前10条数据
select empno,ename,hiredate,sal,deptno,rownum
from emp
where rownum <= 10;
--若按每页5条数据
--查询第一页为前5条数据:1~5
select empno,ename,hiredate,sal,deptno,rownum
from emp
where rownum >= 1 and rownum <= 5;
--查询第二页为后5条数据:6~10
select empno,ename,hiredate,sal,deptno,rownum
from emp
where rownum >= 6 and rownum <= 10;
结论:在第一次进行rownum查询时,不建议使用rownum
做大于判断,否则可能达不到预期效果。
如:上面的第一页有数据,第二页无数据。
原因:rownum默认从1开始,而rownum的编号自增前提
根据条件能查询到下一条数据。查询一条数据,才会
有rownum的自增。而查询语句中where条件中要求
一上来就rownum>=6,这里有矛盾关系,
rownum从1开始,要想rownum>=6,必须使得rownum先
自增到6才行。
所以导致where rownum>=6的条件,永远都不可能满足。
解决方案:如何才能做rownum的大于操作?
先编号,再分页。
--后分页
select empno,ename,hiredate,sal,deptno,temp.num
from(
--先编号
select empno,ename,hiredate,sal,deptno,
rownum num --****给rownum取别名
from emp
) temp
where temp.num >= 6 and temp.num <= 10;
2)、分页要排序
按部门排序
因为:select ruwnum执行顺序在order by之前,
会导致查询的数据,先编号,再排序。
排序的结果比如会导致编号顺序杂乱,也仅仅是
对固定编号内的结果数据,进行小范围的排序而已。
根本也无法实现真正意义上的排序。
结论:排序一定要在编号之前完成。
最后的分页sql就得按照如下顺序:
先排序 、再编号、最后分页
--最后分页
select empno,ename,hiredate,sal,deptno,num
from(
--再编号
select empno,ename,hiredate,sal,deptno,
rownum num --****给rownum去别名
from (
--先排序
select * from emp order by deptno
)
--where rownum <= 10 --小于操作也可以此处。
)
where num >= 6 and num <= 10;--推荐使用这样编写
3)、分页参数
a、pageSize:
每页显示条数(记录数)
即一页多少条数据。
b、pageNum:
页码数
即需要查询为第几页。
举例:每页显示5条
第1页:1~5
第2页:6~10
第3页:11~15
...
第100页:496~50
对应页码的记录数为:
rownum起始位置:
(pageNum - 1) * pageSize + 1
rownum终止位置:
pageNum * pageSize;
4)、终极分页sql
--最后分页
select empno,ename,hiredate,sal,deptno,num
from(
--再编号
select empno,ename,hiredate,sal,deptno,
rownum num --****给rownum去别名
from (
--先排序
select * from emp order by deptno
)
)
where num >= ((pageNum - 1) * pageSize + 1)
and num <= (pageNum * pageSize);
2、高级函数
1)、decode函数
可以实现类似switch-case效果。
语法:
decode(字段名,
search1,result1,
search2,result2,
...
searchN,resultN, --如果没有default,逗号省略
[default]
)
可以使用decode函数,用在两个方面:
①、分组
统计人数
--按照job职位分组统计人数
select job,count(*) from emp
group by job;
--将MANAGER与ANALYST统计为vip组,
--其他职位统计为other组
--要求统计vip与other组的人数。
select decode(job,
'MANAGER','vip',
'ANALYST','vip',
'other'
) 职位,count(*) from emp
group by
decode(job,
'MANAGER','vip',
'ANALYST','vip',
'other'
);
②、排序
--按薪资、部门、job排序
select * from emp
order by job;--按职位的首字母ASIIC码自然排序
--现实中,必须要严格遵循职位重要性来排序。
PRESIDENT
MANAGER
ANALYST
CLERK
SALESMAN
select * from emp
order by
decode(job,
'PRESIDENT',1,
'MANAGER',2,
'ANALYST',3,
'CLERK',4,
5
);
2)、case-when函数
与decode效果一致,但是语法复杂很多,建议使用decode。
语法:
case 字段名
when search1 then result1
when search2 then result2
...
when searchN then resultN
else resultN+1
end;
--现实中,必须要严格遵循职位重要性来排序。
PRESIDENT
MANAGER
ANALYST
CLERK
SALESMAN
select * from emp
order by
(case job
when 'PRESIDENT' then 1
when 'MANAGER' then 2
when 'ANALYST' then 3
when 'CLERK' then 4
else 5
end);
decode(字段名,
search1,result1,
search2,result2,
...
searchN,resultN, --如果没有default,逗号省略
[default]
)
3)、排序函数
查询员工信息,根据部门分组,工资顺序排序。
select * from emp
group by deptno
order by sal;
怎么办???
对于如上组内排序的sql,可以直接使用高级排序函数来实现。
根据排序结果,分为:
①、组内(编号)连续且唯一排序
row_number
语法:row_number() --连续且唯一编号
--按以下规则
over(
partition by 字段1 --按字段1分组
order by 字段2 --按字段2排序
)
如:查询员工信息,根据部门分组,工资顺序排序。
select empno,ename,hiredate,sal,deptno,
(row_number() --连续且唯一编号
--按以下规则
over(
partition by deptno --按字段1分组
order by sal --按字段2排序
)) 连续且唯一
from emp;
②、组内(编号)连续不唯一排序
dense_rank
语法:dense_rank() --连续不唯一编号
--按以下规则
over(
partition by 字段1 --按字段1分组
order by 字段2 --按字段2排序
)
如:查询员工信息,根据部门分组,工资顺序排序。
select empno,ename,hiredate,sal,deptno,
(dense_rank() --连续不唯一编号
--按以下规则
over(
partition by deptno --按字段1分组
order by sal --按字段2排序
)) 连续不唯一编号
from emp;
③、组内(编号)不连续不唯一排序
rank
语法:rank() --不连续不唯一编号
--按以下规则
over(
partition by 字段1 --按字段1分组
order by 字段2 --按字段2排序
)
如:查询员工信息,根据部门分组,工资顺序排序。
select empno,ename,hiredate,sal,deptno,
(rank() --不连续不唯一编号
--按以下规则
over(
partition by deptno --按字段1分组
order by sal --按字段2排序
)) 不连续不唯一编号
from emp;
2、高级函数
1)、分支函数
decode
分支效果。
来实现排序、分组。
case-when与decode函数功能相同
2)、排序函数
row_number():组内连续且唯一。
rank():组内不连续不唯一。
dense_rank():组内连续不唯一。
正课:
1、高级函数
1)、分支函数
2)、排序函数
3)、集合操作
①、并集
union:自动去重联合查询
--得到15条数据
select * from emp -- 员工表集合 15
union
select * from leader;--领导表集合 6
union all:不去重联合查询
--得到21条数据
select * from emp -- 员工表集合 15
union all
select * from leader;--领导表集合 6
②、交集
intersect
--得到6条数据
select * from emp -- 员工表集合 15
intersect
select * from leader;--领导表集合 6
③、差集
minus
集合1 差 集合2
--得到9条数据
select * from emp --员工表集合 15
minus
select * from leader;--领导表集合 6
集合2 差 集合1
--得到0条数据
select * from leader--领导表集合 6
minus
select * from emp;--员工表集合 15