數據庫操作(八)

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
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 一. Java基礎部分.................................................
    wy_sure閱讀 3,835評論 0 11
  • 特別說明: 1、本文只是面對數據庫應用開發的程序員,不適合專業DBA,DBA在數據庫性能優化方面需要了解更多的知識...
    安易學車閱讀 1,860評論 0 40
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,765評論 18 399
  • 索引的基本原理,以及數據是如何被訪問的 (一)SQLS如何訪問沒有建立索引的數據表 Heap譯成漢語叫做“堆”,其...
    安易學車閱讀 3,488評論 0 8
  • 1.人品根植于內心,與地域無關,要有警覺心 2006年7月,我大學畢業,來到北京,在CBD里的一家外企上班。 我,...
    畫心師安語嫣閱讀 917評論 21 46