一、SQL Server Row_number函數簡介
ROW_NUMBER()是一個Window函數,它為結果集的分區中的每一行配置設定一個連續的整數。 行号以每個分區中第一行的行号開頭。
文法執行個體:
select *,row_number() over(partition by column1 order by column2) as n
from tablename
在上面文法中:
- PARTITION BY子句将結果集劃分為分區。 ROW_NUMBER()函數分别應用于每個分區,并重新初始化每個分區的行号。
- PARTITION BY子句是可選的。如果未指定,ROW_NUMBER()函數會将整個結果集視為單個分區。
- ORDER BY子句定義結果集的每個分區中的行的邏輯順序。 ORDER BY子句是必需的,因為ROW_NUMBER()函數對順序敏感
二、Row_number函數的具體用法
1.使用row_number()函數對結果集進行編号
示例:
對test_user表的查詢結果标記行号,并新增 “編号”列傳回
-- 使用 ROW_NUMBER()函數對結果進行編号
select ROW_NUMBER() over(order by id) as 編号,*
from test_user;
運作結果:
可以看到,查詢結果新增了一列,專門用來标記行号。
有了編号,我們就可以友善地進行分頁查詢了,如何操作,可參考另外篇文章:sqlServer如何實作分頁查詢
2.對結果集按照指定列進行分組,并在組内按照指定列排序
示例:
把test_user表的name按照小組進行分組顯示,分組後在組内進行從低到高id排序
-- 使用partition by對結果集進行分組
select *,row_number() over(partition by name order by id) as n
from test_user;
運作結果:
3.對結果集按照指定列去重
示例:
對 test_user表按name進行分組顯示,結果集中隻顯示每組中一條 id最小的資料
select a.* from (
select *,row_number() over(partition by name order by id) as row_id from test_user
) as a
-- 隻查詢組内編号為1的資料
where a.row_id<2;
運作結果:
查詢結果先是經過name分組,然後組内進行id升序排序,組内編号為1的第1條資料,自然就是id最小的資料。
注意:
當我們按成績分數查詢名次等需求時,不能用row_number(),因為如果同班有兩個并列第一,row_number()隻傳回一個結果。這個時候就要用到另外一個函數,rank()和dense_rank()。
rank()和dense_rank()差別:
1、RANK()
在計算排序時,若存在相同位次,會跳過之後的位次。
例如,有3條排在第1位時,排序為:1,1,1,4······
2、DENSE_RANK()
這就是題目中所用到的函數,在計算排序時,若存在相同位次,不會跳過之後的位次。
例如,有3條排在第1位時,排序為:1,1,1,2······