如何在SQL中过滤每组中前1%和下1%的数据

时间:2013-06-14 12:48:10

标签: sql sql-server-2008

我有一个包含PRICE,SUBTYPE等数据集。我想在使用数据集之前先删除异常值。我希望在每个SUBTYPE中删除价格高得离谱或低价的行。

对于每个SUBTYPE,查看PRICE范围并删除或过滤掉行。 保持介于两者之间的行:PRICErange * .01 | KEEP | PRICErange * .99

这是由Martin Smith在stackoverflow上提供的,我编辑了这个问题,所以让我们从这里开始。

;WITH CTE       
AS (SELECT *,                   
ROW_NUMBER() OVER (PARTITION BY SUBTYPE ORDER BY PRICE) AS RN,                    
COUNT(*) OVER(PARTITION BY SUBTYPE) AS Cnt             
FROM    all_resale)    
SELECT *    
FROM   CTE    
WHERE (CASE WHEN Cnt > 1 THEN 100.0 * (RN -1)/(Cnt -1) END) BETWEEN 1 AND 99

我不确定这是我需要做的事情。我不知道将从末端删除多少行。

1 个答案:

答案 0 :(得分:5)

您没有准确指定如何定义1%以及如何处理关系。

一种方法是

;WITH CTE
     AS (SELECT *,
                ROW_NUMBER() OVER (PARTITION BY SUBTYPE ORDER BY PRICE) AS RN,
                COUNT(*) OVER(PARTITION BY SUBTYPE) AS Cnt
         FROM    all_resale)
SELECT *
FROM   CTE
WHERE (CASE WHEN Cnt > 1 THEN 100.0 * (RN -1)/(Cnt -1) END) BETWEEN 1 AND 99

假设最高价格项目为100%,最低价格为0%,其他所有项目均在不考虑关系之间均衡缩放。如果您需要考虑关系,请查看RANK而不是ROW_NUMBER

注意:如果所有子类型都有相对较多的行,则可以使用NTILE(100)代替,但如果行数相对于桶数较小,则不会在桶之间分配。