我有一个这样的示例表:
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
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个百分点,但在每个类别中都没有。有什么建议?
CTE
PARTITIONBY
您可以将CTE(公用表表达式)与NTILE开窗功能配对使用-这会将您的数据切成所需的任意数量的切片,例如在您的情况下,分成20个切片(每个5%)。
NTILE
;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中进行选择时,只需忽略该切片即可。
Category,Name
COUNT(Name)
NTile = 1