選讀SQL經典實例筆記15_視窗函數

来源:https://www.cnblogs.com/lying7/archive/2023/08/02/17596697.html
-Advertisement-
Play Games

![](https://img2023.cnblogs.com/blog/3076680/202308/3076680-20230801154428674-66504638.png) # 1. 分組 ## 1.1. 把相似的行數據聚集在一起 # 2. SQL分組的定義 ## 2.1. 數學上的“群” ...


1. 分組

1.1. 把相似的行數據聚集在一起

2. SQL分組的定義

2.1. 數學上的“群”(group)定義為 (G, •,e),其中G是一個集合,• 表示G的二進位運算,而e則是G中的成員

2.2. 一個SQL 分組須滿足的兩個定理

2.2.1. 對於G的每一個成員e,e具有唯一性,並且存在一個或者多個e的實例

2.2.1.1. 分組不為空

2.2.1.1.1. 一個分組至少要擁有一個成員(行
2.2.1.1.2. 無法從一個空表中生成任何分組

2.2.1.2. 分組具有唯一性

2.2.1.2.1. 如果查詢語句使用了GROUP BY子句,那麼通常而言SELECT列表裡就不再需要使用DISTINCT關鍵字了

2.2.2. 對於G的每一個成員e,聚合函數COUNT的返回值大於0

2.2.2.1. COUNT永遠大於0

2.2.2.1.1. 無法從一個空表裡生成分組,因此一個分組至少會含有1行數據
2.2.2.1.2. 既然至少有1行數據,那麼COUNT查詢的結果自然至少等於1
2.2.2.1.3. 同時使用COUNT和GROUP BY的狀況
2.2.2.1.4. 如果不要GROUP BY子句,針對一個空表執行COUNT查詢當然會得到0
2.2.2.1.4.1. 只使用COUNT的狀況

2.3. SQL 分組的概念依存於SQL 查詢,沒有SQL 查詢就不會有SQL 分組

2.4. SQL 分組在技術上指的就是由行數據構成的結果集

3. PARTITION BY子句

3.1. 針對行數據進行分區(partition)或者分組(group),並根據其結果執行聚合運算

3.2. “動態的GROUP BY”

3.2.1. 在最終的結果集中允許出現多種由PARTITION BY生成的分區

3.3. 在同一個SELECT語句里我們可以按照不同的列進行分區,而且不同的視窗函數調用之間互不影響

4. Null的影響

4.1. 所有的Null歸入同一個分區或者分組

4.2. COUNT(column)會忽略Null

4.3. 如果希望把NULL值一併計入,則應該使用COUNT(*)

5. 使用視窗函數的代碼顯得短小精悍

5.1. sql

 select deptno,
       job,
       count(*) over (partition by deptno) as emp_cnt,
       count(job) over (partition by deptno,job) as job_cnt,
       count(*) over () as total
  from emp
DEPTNO JOB          EMP_CNT    JOB_CNT      TOTAL
------ --------- ---------- ---------- ----------
    10 CLERK              3          1         14
    10 MANAGER            3          1         14
    10 PRESIDENT          3          1         14
    20 ANALYST            5          2         14
    20 ANALYST            5          2         14
    20 CLERK              5          2         14
    20 CLERK              5          2         14
    20 MANAGER            5          1         14
    30 CLERK              6          1         14
    30 MANAGER            6          1         14
    30 SALESMAN           6          4         14
    30 SALESMAN           6          4         14
    30 SALESMAN           6          4         14
    30 SALESMAN           6          4         14

5.1.1. 視窗函數的出現使得許多通常被認為單純使用標準SQL 難以解決的問題變得較為容易了

6. 使用多個自連接和標量子查詢

6.1. sql

select a.deptno, a.job,
       (select count(*) from emp b
         where b.deptno = a.deptno) as emp_cnt,
       (select count(*) from emp b
         where b.deptno = a.deptno and b.job = a.job) as job_cnt,
       (select count(*) from emp) as total
  from emp a
 order by 1,2
DEPTNO JOB          EMP_CNT    JOB_CNT      TOTAL
------ --------- ---------- ---------- ----------
    10 CLERK              3          1         14
    10 MANAGER            3          1         14
    10 PRESIDENT          3          1         14
    20 ANALYST            5          2         14
    20 ANALYST            5          2         14
    20 CLERK              5          2         14
    20 CLERK              5          2         14
    20 MANAGER            5          1         14
    30 CLERK              6          1         14
    30 MANAGER            6          1         14
    30 SALESMAN           6          4         14
    30 SALESMAN           6          4         14
    30 SALESMAN           6          4         14
    30 SALESMAN           6          4         14

7. 視窗函數DENSE_RANK OVER

7.1. sql

select max(case grp when 1 then rpad(ename,6) ||
                    ' ('|| sal ||')' end) top_3,
       max(case grp when 2 then rpad(ename,6) ||
                    ' ('|| sal ||')' end) next_3,
       max(case grp when 3 then rpad(ename,6) ||
                    ' ('|| sal ||')' end) rest
  from (
select ename,
       sal,
       rnk,
       case when rnk <= 3 then 1
            when rnk <= 6 then 2
            else 3
       end grp,
       row_number()over (
         partition by case when rnk <= 3 then 1
                           when rnk <= 6 then 2
                           else 3
                       end
             order by sal desc, ename
       ) grp_rnk
  from (
select ename,
       sal,
       dense_rank()over(order by sal desc) rnk
  from emp
       ) x
       ) y
 group by grp_rnk
TOP_3           NEXT_3          REST
--------------- --------------- -------------
KING   (5000)   BLAKE  (2850)   TURNER (1500)
FORD   (3000)   CLARK  (2450)   MILLER (1300)
SCOTT  (3000)   ALLEN  (1600)   MARTIN (1250)
JONES  (2975)                   WARD   (1250)
                                ADAMS  (1100)
                                JAMES  (950)
                                SMITH  (800)

7.2. 視窗函數最為引人註目的功能之一就是,只需訪問一次原始數據就可以完成很多複雜的任務

7.3. 不需要自連接或臨時表,只要準備好必要的基礎數據集,剩下的工作交給視窗函數處理就行了

8. 為兩次變換後的結果集增加列標題

8.1. sql

select * from it_research
DEPTNO ENAME
------ --------------------
   100 HOPKINS
   100 JONES
   100 TONEY
   200 MORALES
   200 P.WHITAKER
   200 MARCIANO
   200 ROBINSON
   300 LACY
   300 WRIGHT
   300 J.TAYLOR
select * from it_apps
DEPTNO ENAME
------ -----------------
   400 CORRALES
   400 MAYWEATHER
   400 CASTILLO
   400 MARQUEZ
   400 MOSLEY
   500 GATTI
   500 CALZAGHE
   600 LAMOTTA
   600 HAGLER
   600 HEARNS
   600 FRAZIER
   700 GUINN
   700 JUDAH
   700 MARGARITO

8.2. sql

RESEARCH             APPS
-------------------- ---------------
100                  400
  JONES                MAYWEATHER
  TONEY                CASTILLO
  HOPKINS              MARQUEZ
200                    MOSLEY
  P.WHITAKER           CORRALES
  MARCIANO           500
  ROBINSON             CALZAGHE
  MORALES              GATTI
300                  600
  WRIGHT               HAGLER
  J.TAYLOR             HEARNS
  LACY                 FRAZIER
                       LAMOTTA
                     700
                       JUDAH
                       MARGARITO
                       GUINN

8.3. sql

select max(decode(flag2,0,it_dept)) research,
        max(decode(flag2,1,it_dept)) apps
   from (
 select sum(flag1)over(partition by flag2
                           order by flag1,rownum) flag,
        it_dept, flag2
   from (
 select 1 flag1, 0 flag2,
        decode(rn,1,to_char(deptno),'  '||ename) it_dept
   from (
 select x.*, y.id,
        row_number()over(partition by x.deptno order by y.id) rn
   from (
 select deptno,
        ename,
        count(*)over(partition by deptno) cnt
   from it_research
        ) x,
        (select level id from dual connect by level <= 2) y
        )
  where rn <= cnt+1
 union all
 select 1 flag1, 1 flag2,
        decode(rn,1,to_char(deptno),'  '||ename) it_dept
   from (
 select x.*, y.id,
        row_number()over(partition by x.deptno order by y.id) rn
   from (
 select deptno,
        ename,
        count(*)over(partition by deptno) cnt
   from it_apps
        ) x,
        (select level id from dual connect by level <= 2) y
        )
  where rn <= cnt+1
        ) tmp1
        ) tmp2
  group by flag

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這篇文章介紹了什麼是事件,以及如何在C#中使用事件。事件是在生活中發生的事情,它涉及到事件的發佈者和事件的訂閱者,當事件發生時,發佈者會發佈消息,訂閱者會接收通知並做出相應的處理。在C#中,我們可以使用event關鍵字定義一個事件,然後訂閱和取消事件的方法與委托鏈的取消和鏈接相同。 ...
  • ## 引言 現在模擬一個非同步方法拋出了異常: ```csharp public static async Task ThrowAfter(int ms, string message) { await Task.Delay(ms); throw new Exception(message); } ` ...
  • 一、TextBox在輸入框回車時會觸發其他事件,如何解決? 前臺代碼: <ul> <li><span>名稱:</span><asp:TextBox ID="txtCategoryName" runat="server" CssClass="forminput form-control"></asp: ...
  • ASP.NET Core WebAPI如何獲得遠程文件返迴文件流給前端?項目採用的是前後端分離的模式,後端使用ASP.NET Core WebAPI方式,將文件流返回給前端。 ...
  • Repeater 控制項用於顯示被綁定在該控制項上的項目的重覆列表。Repeater 控制項可被綁定到資料庫表、XML 文件或者其他項目列表。 GridView 控制項,通過使用 GridView 控制項,您可以顯示、編輯和刪除多種不同的數據源(例如資料庫、XML 文件和公開數據的業務對象)中的數據。 ...
  • 博客推行版本更新,成果積累制度,已經寫過的博客還會再次更新,不斷地琢磨,高質量高數量都是要追求的,工匠精神是學習必不可少的精神。因此,大家有何建議歡迎在評論區踴躍發言,你們的支持是我最大的動力,你們敢投,我就敢肝 ...
  • # 當我們想要體驗體驗不同類型的Linux的使用技巧,節省個人開銷,可以在Windows系統上創建其他系統的虛擬機,可以創建虛擬機常用的應用有: VMware Station VirtualBox 此篇文章使用VirtualBox,結合Vagrant來實現Linux虛擬機的創建。使用這兩種應用結合的 ...
  • ### 企業現狀 **目前絕大多數企業運維人員的工作環境都是Windows下通過SSH工具(如XShell等)遠程連接千百裡外的伺服器進行管理和維護的。** 而且學Linux運維,99.9%知識與硬體無關,用虛擬機足矣。 08年以前沒有虛擬化概念。買伺服器,放機房。 > 類似點蠟燭 **現在80%中 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...