通常這種類型的查詢被稱爲top-N-per-group
。在SQL Server中至少有兩種獲取結果的方法。一個使用ROW_NUMBER
,另一個使用CROSS APPLY
。如果每組有很多組和很少的行,那麼使用ROW_NUMBER
會更有效。如果您的組數很少,但每個組都有很多行,並且您有適當的索引,則使用CROSS APPLY
會更有效。
https://dba.stackexchange.com/questions/86415/retrieving-n-rows-per-group
http://sqlmag.com/sql-server/seek-and-you-shall-scan-part-i-when-optimizer-doesnt-optimize
樣本數據
DECLARE @T TABLE
([key] int,
[entry_no] int,
[type_1] varchar(1),
[type_2] varchar(1),
[text] varchar(50));
INSERT INTO @T
([key], [entry_no], [type_1], [type_2], [text])
VALUES
(1, 1, 'A', 'Y', 'text 1'),
(1, 2, 'B', 'Y', 'text 2'),
(1, 3, 'B', 'Y', 'text 3'),
(1, 4, 'A', 'Y', 'text 4'),
(1, 5, 'B', '', 'text 5'),
(1, 6, 'C', 'Y', 'text 6');
變體與ROW_NUMBER
DECLARE @VarKey int = 1;
WITH
CTE
AS
(
SELECT
[key]
,[entry_no]
,[type_1]
,[type_2]
,[text]
,ROW_NUMBER()
OVER (PARTITION BY [type_1] ORDER BY [entry_no] DESC) AS rn
FROM @T
WHERE
[key] = @VarKey
AND [type_2] = 'Y'
)
SELECT
[key]
,[entry_no]
,[type_1]
,[type_2]
,[text]
FROM CTE
WHERE rn = 1
ORDER BY [type_1];
結果
| key | entry_no | type_1 | type_2 | text |
|-----|----------|--------|--------|--------|
| 1 | 4 | A | Y | text 4 |
| 1 | 3 | B | Y | text 3 |
| 1 | 6 | C | Y | text 6 |
請編輯的問題,並添加一個標籤與您所使用的數據庫管理系統(Postgres的時,SQL Server,Oracle等)及其版本。除非你需要ANSI標準SQL的解決方案。 –
標籤根據要求更新。 – jj2