MSSQL—按照某一列分組后取前N條記錄


以前在開發的時候遇到過一個需求,就是要按照某一列進行分組后取前幾條數據,今天又有同事碰到了,幫解決了之后順便寫一篇博客記錄一下。

首先先建一個基礎數據表,代碼如下:

IF OBJECT_ID(N'Test') IS NOT NULL
    BEGIN
        DROP TABLE Test
    END

CREATE TABLE Test(
ID bigint IDENTITY(1,1),
Name nvarchar(50),
Department nvarchar(50))
       

INSERT INTO Test(Name,Department)
VALUES('張三','行政'),
('李四','運營'),
('王五','行政'),
('趙六','研發'),
('錢七','工程'),
('Amy','研發'),
('Tomy','工程'),
('Tony','研發'),
('Tom','工程'),
('Alice','行政'),
('Mary','行政'),
('Elaine','運營'),
('Geno','行政'),
('Gary','工程')
GO

建好后,這張表的數據如下:

image

現在的需求是按照Department列進行分組,按ID取每個部門前2條記錄,只寫一條SQL語句的話,分別可以用3種方法實現,代碼如下:

SELECT ID,Name,Department FROM
(SELECT nn=ROW_NUMBER() OVER(PARTITION BY Department ORDER BY ID),*  FROM Test) b WHERE nn<=2

 
SELECT * FROM Test t WHERE
(SELECT COUNT(*) FROM Test WHERE Department=t.Department AND ID<=t.ID)<=2 ORDER BY Department


SELECT * FROM Test t
WHERE ID in (SELECT DISTINCT TOP 2 ID FROM Test WHERE Department=t.Department)
ORDER BY Department

第一種方法使用了ROW_NUMBER()函數,這個函數是在SQL 2005及以上版本才有的,所以如果數據庫是2000的話只能用下面兩種方法,運行之后得到的結果都一樣,如下圖:

image

總結,碰到此類需求可以直接用下面代碼進行套用:

SELECT 要輸出的列,除nn外 FROM
(SELECT nn=ROW_NUMBER() OVER(PARTITION BY 分組的列 ORDER BY 排序的列),*  FROM 表名) b WHERE nn<=前N條數據

 
SELECT * FROM 表名 t WHERE
(SELECT COUNT(*) FROM 表名 WHERE 分組的列=t.分組的列 AND 排序的列<=t.排序的列)<=前N條數據 ORDER BY 分組的列


SELECT * FROM 表名 t
WHERE 排序的列 in (SELECT DISTINCT TOP 前N條數據 排序的列 FROM 表名 WHERE 分組的列=t.分組的列)
ORDER BY 分組的列


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM