SQL:在标准差内显示平均值和最小值/最大值

时间:2010-03-05 02:07:26

标签: sql sql-server-2005

我有以下SQL表 -

Date       StoreNo       Sales
23/4            34     4323.00
23/4            23      564.00
24/4            34     2345.00
etc

我正在运行一个查询,该查询返回特定时期的平均销售额,最大销售额和最低销售额 -

select avg(Sales), max(sales), min(sales)
from tbl_sales
where date between etc

但是在最小值和最大值中有一些值非常极端 - 也许是因为数据输入很糟糕,可能是因为在那个日期和商店发生了一些异常现象。

我想要的是一个返回平均值,最大值和最小值的查询,但不知何故排除了极值。我对如何完成这项工作持开放态度,但也许它会以某种方式使用标准偏差(例如,仅使用真实平均值的x std devs内的数据)。

非常感谢

3 个答案:

答案 0 :(得分:3)

为了计算标准偏差,您需要遍历所有元素,因此在一个查询中无法执行此操作。懒惰的方式是两次通过:

DECLARE
    @Avg int,
    @StDev int

SELECT @Avg = AVG(Sales), @StDev = STDEV(Sales)
FROM tbl_sales
WHERE ...

SELECT AVG(Sales) AS AvgSales, MAX(Sales) AS MaxSales, MIN(Sales) AS MinSales
FROM tbl_sales
WHERE ...
AND Sales >= @Avg - @StDev * 3
AND Sales <= @Avg + @StDev * 3

可能工作的另一个简单选项(在分析科学数据时相当常见)就是删除最小和最大 x 值,如果你有一个要处理的大量数据。您可以使用ROW_NUMBER在一个语句中执行此操作:

WITH OrderedValues AS
(
    SELECT
        Sales,
        ROW_NUMBER() OVER (ORDER BY Sales) AS RowNumAsc,
        ROW_NUMBER() OVER (ORDER BY Sales DESC) AS RowNumDesc
)
SELECT ...
FROM tbl_sales
WHERE ...
AND Sales >
(
    SELECT MAX(Sales)
    FROM OrderedValues
    WHERE RowNumAsc <= @ElementsToDiscard
)
AND Sales <
(
    SELECT MIN(Sales)
    FROM OrderedValues
    WHERE RowNumDesc <= @ElementsToDiscard
)

如果要丢弃一定数量的唯一值,请将ROW_NUMBER替换为RANKDENSE_RANK

除了这些简单的技巧,你开始进入一些相当沉重的统计数据。我必须处理类似的验证,这对SO帖子来说太多了。您可以通过十几种不同的方式调整一百种不同的算法。如果可能的话,我会尽量保持简单!

答案 1 :(得分:2)

扩展DuffyMo的帖子你可以做类似

的事情
With SalesStats As
    (
    Select Sales, NTILE( 100 ) OVER ( Order By Sales ) As NtileNum
    From tbl_Sales
    )
Select Avg( Sales ), Max( Sales ), Min( Sales )
From SalesStats
Where NtileNum Between 5 And 95

这将排除最低5%和最高95%。如果您的数字变化很大,您可能会发现平均值不是质量摘要统计信息,应考虑使用中位数。你可以通过以下方式做到这一点:

With SalesStats As
    (
    Select NTILE( 100 ) OVER ( Order By Sales ) As NtileNum
        , ROW_NUMBER() OVER ( Order By Id ) As RowNum
    From tbl_Sales
    )
    , TotalSalesRows
        (
        Select COUNT(*) As Total
        From tbl_Sales
        )
    , Median As
        (
        Select Sales 
        From SalesStats
            Cross Join TotalSalesRows
        Where RowNum In ( (TotalRows.Total + 1) / 2, (TotalRows.Total + 2) / 2 )
        )
Select Avg( Sales ), Max( Sales ), Min( Sales ), Median.Sales
From SalesStats
    Cross Join Median
Where NtileNum Between 5 And 95

答案 2 :(得分:1)

也许您正在寻找的是percentiles

标准差往往对异常值敏感,因为它是使用值与平均值之差的平方来计算的。

在你的情况下,一个更稳健,更不敏感的衡量标准,例如价值与均值之间的差异的绝对值,可能会更合适。