Leg*_*end 12 sql t-sql sql-server sql-server-2008 greatest-n-per-group
我有一个这样的样本表:
CREATE TABLE #TEMP(Category VARCHAR(100), Name VARCHAR(100))
INSERT INTO #TEMP VALUES('A', 'John')
INSERT INTO #TEMP VALUES('A', 'John')
INSERT INTO #TEMP VALUES('A', 'John')
INSERT INTO #TEMP VALUES('A', 'John')
INSERT INTO #TEMP VALUES('A', 'John')
INSERT INTO #TEMP VALUES('A', 'John')
INSERT INTO #TEMP VALUES('A', 'Adam')
INSERT INTO #TEMP VALUES('A', 'Adam')
INSERT INTO #TEMP VALUES('A', 'Adam')
INSERT INTO #TEMP VALUES('A', 'Adam')
INSERT INTO #TEMP VALUES('A', 'Lisa')
INSERT INTO #TEMP VALUES('A', 'Lisa')
INSERT INTO #TEMP VALUES('A', 'Bucky')
INSERT INTO #TEMP VALUES('B', 'Lily')
INSERT INTO #TEMP VALUES('B', 'Lily')
INSERT INTO #TEMP VALUES('B', 'Lily')
INSERT INTO #TEMP VALUES('B', 'Lily')
INSERT INTO #TEMP VALUES('B', 'Lily')
INSERT INTO #TEMP VALUES('B', 'Tom')
INSERT INTO #TEMP VALUES('B', 'Tom')
INSERT INTO #TEMP VALUES('B', 'Tom')
INSERT INTO #TEMP VALUES('B', 'Tom')
INSERT INTO #TEMP VALUES('B', 'Ross')
INSERT INTO #TEMP VALUES('B', 'Ross')
INSERT INTO #TEMP VALUES('B', 'Ross')
SELECT Category, Name, COUNT(Name) Total
FROM #TEMP
GROUP BY Category, Name
ORDER BY Category, Total DESC
DROP TABLE #TEMP
Run Code Online (Sandbox Code Playgroud)
给我以下内容:
A John 6
A Adam 4
A Lisa 2
A Bucky 1
B Lily 5
B Tom 4
B Ross 3
Run Code Online (Sandbox Code Playgroud)
现在,我该如何选择TOP 5 PERCENT从每个类别记录假设每个类别都有超过100条记录(未在样本表显示这里)?举例来说,在我实际的表,它应该删除John从记录A和Lily从唱片B(再说一次,我没有表现出全表这里)酌情获得:
A Adam 4
A Lisa 2
A Bucky 1
B Tom 4
B Ross 3
Run Code Online (Sandbox Code Playgroud)
我一直在尝试使用CTEs和PARTITION BY子句,但似乎无法实现我想要的.它从总体结果中删除了TOP 5 PERCENT,但不从每个类别中删除.有什么建议?
mar*_*c_s 17
您可以使用与NTILE窗口函数配对的CTE(公用表表达式)- 这会将您的数据切片为您需要的多个切片,例如在您的情况下,切成20个切片(每个5%).
;WITH SlicedData AS
(
SELECT Category, Name, COUNT(Name) Total,
NTILE(20) OVER(PARTITION BY Category ORDER BY COUNT(Name) DESC) AS 'NTile'
FROM #TEMP
GROUP BY Category, Name
)
SELECT *
FROM SlicedData
WHERE NTile > 1
Run Code Online (Sandbox Code Playgroud)
这基本上将您的数据分组Category,Name,按其他方式排序(不确定是否COUNT(Name)真的是您想要的东西),然后将其分成20个部分,每个部分代表5%的数据分区.切片NTile = 1是最高的5%切片 - 从CTE中选择时忽略它.
看到:
了解更多信息