LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

Sqlserver OVER(PARTITION BY)的簡單理解

freeflydom
2023年10月28日 15:22 本文熱度 873

ROW_NUMBER() OVER(…)

  1. 雖然寫法很復雜,但這確實只是一個普通函數(就像字符串轉數字這樣的函數),可以得出一個值

  2. 這個函數不會改變數據條數,它的作用是給每個數據記錄增加一個字段,這個字段值就是函數得到的值

  3. 函數雖然不會改變查詢結果條數,但會改變結果的順序。會按照某個字段a(這個字段會重復)分組,函數的值就是在每個分組內部的排序值(1,2,3,4.。。)

  4. 比如:一群人在排隊買東西。會自動以家庭為單位分成一段一段的“小組”,然后又在家庭內部按照年齡大小做了排序(比如年齡大人在前面,小孩跟在大人后面),這個函數值就是這個家庭內部排序值

  5. 按照上面的比喻,這個函數就是ROW_NUMBER() over (PARTITION BY 家庭編號 order by 年齡)

  6. 函數完整的樣子:ROW_NUMBER() OVER(PARTITION BY… ORDER BY…)。為什么要很啰嗦的再加一個ROW_NUMBER()? 因為前面這個ROW_NUMBER()會進一步控制函數的特性,后面會講解【不過我個人認為這個前綴確實很啰嗦。讓我設計的話,我會去掉它。因為對于大部分人可能就只會用最普通的函數使用方式,不寫時就默認為ROW_NUMBER()多好】

類比一個完整的查詢

select *, ROW_NUMBER() over (PARTITION BY 家庭編號 order by 年齡 desc) as “家庭地位” from 人員表
這句話除了得到了所有人員的信息之外,還額外得到了一個字段"家庭地位"(這里就默認:年齡越大,家庭地位越高)

理解了函數的含義和用法,然后我們就可以利用函數,比如,只獲取所有家庭地位最高的人,那么就可以在我們再包一層,得到:
select * from( select *, ROW_NUMBER() over (PARTITION BY 家庭編號 order by 年齡 desc) as “家庭地位” from 人員表 ) t where t.家庭地位=1

引申

這樣就可以解決類似:表T中 字段a會重復,但我們查詢的結果又不想要重復的數據,并且要求只要其中最新的那一條
select * from( select *, ROW_NUMBER() over (PARTITION BY a order by create_time desc) as index from T ) t where t.index=1

或者topN問題:分組后,把每組前5個找出來
select * from( select *, ROW_NUMBER() over (PARTITION BY a order by create_time desc) as index from T ) t where t.index < 6

ROW_NUMBER()

這是一個控制 OVER函數特性的參數,而且不能省,over前面必須有一個。但并不是只有ROW_NUMBER()這一種。

假設在一共家庭中,有四個孩子,其中兩個是雙胞胎,年齡分別是5歲,7歲,7歲,9歲。
兩個7歲的雙胞胎 誰大誰小是很難說。理論上可以講,兩個孩子年齡是相同的。那么排隊時,誰是老大誰是老二呢。
ROW_NUMBER():簡單粗暴的做了自己的判斷,哪條數據在前面,哪個就是老大(誰先生出來誰就是老大)。即便他們年齡一樣(over函數值一樣),它給這幾個孩子定的家庭地位分別為4,3,2,1
DENSE_RENK():顯得更公正一點:既然定好了按年齡排序,那么年齡相同,地位就是相同。它給四個孩子定的家庭地位分別為:3,2,2,1
RENK():比較特殊,它覺得那個5歲的孩子的家庭地位不應該是第3位。因為家里明明有4個孩子,它是最小的,兩個并列第二之后,下一個應該是4(所以直接把3給跳過了)。所以它給的家庭地位分別是4,2,2,1

名稱

下面這些都是這個函數的名稱:
窗口函數分析函數分區函數,一般稱為窗口函數(window function)。
一般關系型數據庫都支持。由于屬于比較高級的函數,都是在數據庫不斷完善的過程中增加的。比如mysql就是8.x之后才有。

和聚合函數對比

聚合函數:sum(), avg() 等統計函數 配合 group by 稱為聚合函數
得出的是分組后 每一組等統計數據,改變了數據條數
如果想保持數據原有的樣子,則需要使用窗口函數

窗口函數前面除了前面介紹的常用的三種,還可以使用sum() avg()等統計函數,變成:
sum() over(partition by ...) x
這里得到的x,就是對這個組內的求和,組內每一條數據都得到一個相同的值

進階-和排序函數對比

雖然前面說窗口函數的核心是partition by,但實際上partition by也可以去掉。
也就是說:xxx() over(…) 這個函數非常靈活。
其中partition by也可去掉,但此時必須要有order by。
變成:xxx() over(order by …) xxx
此時窗口函數 的窗口就只有一個了:所有數據都在同一個窗口里。 只剩下排序功能,比如
dense_renk() over(over by 成績) 名次
常見作用:給班級學生成績排名,成績一樣的,名次就一樣


————————————————

版權聲明:本文為CSDN博主「發現存在」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。

原文鏈接:https://blog.csdn.net/yunduanyou/article/details/122583303



該文章在 2023/10/28 15:25:45 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
亚洲欧美日本A∨天堂 | 日本欧美大码aⅴ在线播放 在线免费播放AV片 亚洲欧美综合香蕉 | 另类专区亚洲色 | 视频一区网友自拍第二页 | 亚洲aⅴ欧美综合一区二区三区 | 亚洲无中文字幕 |