我有一个像这样的示例表:
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 条记录(此处的示例表中未显示),如何从每个类别中选择前 5%
记录?例如,在我的实际表中,它应该从 A
中删除 John
记录,并从 B
中删除 Lily
记录,如下所示适当的(同样,我没有在这里显示完整的表格)得到:
A Adam 4
A Lisa 2
A Bucky 1
B Tom 4
B Ross 3
我一直在尝试使用CTE
和PARTITION BY
子句,但似乎无法实现我想要的。它从总体结果中删除了前 5%,但没有从每个类别中删除。有什么建议吗?
最佳答案
您可以使用 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 block ,每 block 代表数据分区的 5%。 NTile = 1
的切片是前 5% 的切片 - 从 CTE 中选择时忽略它即可。
参见:
- MSDN docs on NTILE
- SQL Server 2005 ranking functions
- SQL SERVER – 2005 – Sample Example of RANKING Functions – ROW_NUMBER, RANK, DENSE_RANK, NTILE
了解更多信息
关于sql - 如何从每组中选择前 5%?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7579916/