今天在公司寫代碼的時候,遇到一個sql語句構建問題。
情形是這樣的:
我需要獲取不同小組下前N條記錄。
select top 10 * from dbo.Topic where GroupID in (60034,60037) and State=0 order by CrtTime desc
很明顯,這是錯的,不僅沒group by,獲取出來的還是按兩個小組的創建時間的前10條數據。
可是,用group by的話,它有個很不通人性的特性。即是——凡是在group by后面出現的字段,必須同時在select后面出現;凡是在select后面出現的、同時未在聚合函數中出現的字段,必須同時出現在group by后面。
這樣就讓我不得不放棄使用group by來分組查詢。
后來在網上找到,分組,不一定要用group by來實現。用row_number() over()同樣可以實現。
語法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)
簡單的說row_number()從1開始,為每一條分組記錄返回一個數字,這里的ROW_NUMBER() OVER (ORDER BY xlh DESC) 是先把xlh列降序,再為降序以后的沒條xlh記錄返回一個序號。
row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根據COL1分組,在分組內部根據 COL2排序,而此函數計算的值就表示每組內部排序后的順序編號(組內連續的唯一的)
有了這么一個函數存在,最終我構建了我的sql語句:
select *
from
(
select *,row_number() over (partition by GroupID order by CrtTime desc) rank from Topic where State=0
) T
where T.rank<=10 and T.GroupID in(60034,60040)
實現了這么一個功能:從不同的組別(60034,60040)里獲取到了按創建時間降序排序的各個小組里的前10條記錄。
參考文章:sql查詢-分組
SQL ROW_NUMBER() OVER函數的基本用法用法
