虽然你可以做到
DECLARE @N INT = 20
SELECT TOP (@n) PERCENT * FROM BLAH
我无法为您数据中的每个组设置@N(CROSS APPLY 任何人?)。
所以这是一个使用两个 CTE 的解决方案。这可能远非最佳:)
测试数据
SELECT *
INTO #Test
FROM (VALUES
(1, 'A', 'CAT-1', 60),
(2, 'B', 'CAT-1', 60),
(3, 'C', 'CAT-1', 60),
(4, 'D', 'CAT-1', 60),
(5, 'E', 'CAT-1', 60),
(6, 'F', 'CAT-2', 30),
(7, 'G', 'CAT-2', 30),
(8, 'H', 'CAT-2', 30),
(9, 'I', 'CAT-3', 10),
(10, 'J', 'CAT-3', 10),
(11, 'K', 'CAT-1', 60)
) A (RowID, Customer, Category, Percentage)
解决方案
在这里,我对第一个 CTE 中的每个组进行排名和计数,然后在第二个 CTE 中设置“百分比括号范围”(这是为了捕获例如前 10% 的查询,其中只有两行括号是50% 和 100%)。
;WITH Ranked AS (
SELECT *,
RANK() OVER (PARTITION BY Category ORDER BY RowId) * 100 RANK,
COUNT(*) OVER (PARTITION BY Category ) COUNT
FROM #Test),
Grouped AS (
SELECT *,
COALESCE(LAG(RANK) OVER (PARTITION BY Category order BY Rank) / COUNT, 0) BracketStart,
RANK / COUNT BracketEnd
FROM Ranked
)
SELECT
G.RowID
,G.Customer
,G.Category
FROM Grouped G
WHERE G.BracketEnd <= G.Percentage OR G.Percentage BETWEEN G.BracketStart AND G.BracketEnd
ORDER BY G.Category
RowID Customer Category
----------- -------- --------
1 A CAT-1
2 B CAT-1
3 C CAT-1
4 D CAT-1
6 F CAT-2
9 I CAT-3