SQL: Показать среднее и мин / макс в пределах стандартных отклонений - PullRequest
2 голосов
/ 05 марта 2010

У меня есть следующая таблица 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 ]

3 голосов
/ 05 марта 2010

Чтобы рассчитать стандартное отклонение, вам нужно выполнить итерацию по всем элементам, поэтому было бы невозможно сделать это за один запрос. Ленивым способом было бы просто сделать это в два прохода:

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 на RANK или DENSE_RANK, если вы хотите отбросить определенное количество уникальных значений.

Помимо этих простых трюков, вы начинаете получать довольно тяжелую статистику. Мне приходится иметь дело с подобными видами валидации, и это слишком много материала для поста SO. Существуют сотни различных алгоритмов, которые вы можете настроить десятком различных способов. Я бы постарался сделать это простым, если это возможно!

2 голосов
/ 05 марта 2010

Расширяя пост 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
1 голос
/ 05 марта 2010

Возможно, вы ищете процентили .

Стандартное отклонение имеет тенденцию быть чувствительным к выбросам, поскольку оно рассчитывается с использованием квадрата разности между значением и средним.

Возможно, в вашем случае более подходящим является более надежный и менее чувствительный показатель, такой как абсолютное значение разности между значением и средним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...