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