一尘不染

如何从每个组中选择TOP 5%?

sql

我有一个这样的示例表:

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

给我以下内容:

A   John    6
A   Adam    4
A   Lisa    2
A   Bucky   1
B   Lily    5
B   Tom     4
B   Ross    3

现在, 假设每个类别有100条以上的记录(未在此处的示例表中显示), 我如何TOP 5 PERCENT从每个类别中选择记录?例如,在我的实际表中,它应该从中删除记录,并从中适当地删除记录(再次,我在这里没有显示完整的表)以获取:
__John``A``Lily``B

A   Adam    4
A   Lisa    2
A   Bucky   1
B   Tom     4
B   Ross    3

我一直在尝试使用CTEs和PARTITIONBY子句,但似乎无法实现我想要的。它从总体结果中删除了前5个百分点,但在每个类别中都没有。有什么建议?


阅读 128

收藏
2021-03-17

共1个答案

一尘不染

您可以将CTE(公用表表达式)与NTILE开窗功能配对使用-这会将您的数据切成所需的任意数量的切片,例如在您的情况下,分成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

基本上Category,Name,这将您的数据按照进行分组COUNT(Name),再按其他顺序(不确定是否确实是您想要的东西)进行分组,然后将其切成20个片段,每个片段代表您数据分区的5%。具有的切片NTile = 1是前5%的切片-从CTE中进行选择时,只需忽略该切片即可。

2021-03-17