2013-10-25 3 views
-1
CREATE FUNCTION [dbo].[f_Get_Average_Order_Size_Median] 
(
     @ITEM char(15) 
) 
RETURNS decimal(21,6) 
AS 
BEGIN 

SELECT @Median = AVG(1.0 * QTYSHP) 
FROM 
(
    SELECT o.QTYSHP, rn = ROW_NUMBER() OVER (ORDER BY o.QTYSHP), c.c 
    FROM dbo.tbl AS o 
     WHERE RQDATE >=DATEADD (mm,-6, GETDATE()) 
     AND PRICE != '0' 
     AND SALESMN != 'WB' 
     AND item = @ITEM) 

    + 
    SELECT o.QTYSHP, rn = ROW_NUMBER() OVER (ORDER BY o.QTYSHP), c.c 
    FROM tbl 
     WHERE RQDATE >=DATEADD (mm,-6, GETDATE()) 
     AND PRICE != '0' 
     AND SALESMN != 'WB' 
     AND item = @ITEM 
    CROSS JOIN (SELECT c = COUNT(*) 
       FROM dbo.tblS) AS c 
        WHERE RQDATE >=DATEADD (mm,-6, GETDATE()) 
        AND PRICE != '0' 
        AND SALESMN != 'WB' 
        AND item = @ITEM 
    + 
    (SELECT c = COUNT(*) 
    FROM dbo.tblS) AS c 
     WHERE RQDATE >=DATEADD (mm,-6, GETDATE()) 
     AND PRICE != '0' 
     AND SALESMN != 'WB' 
     AND item = @ITEM 
    ) AS x 
WHERE rn IN ((c + 1)/2, (c + 2)/2); 


     @Return = @Median 
     BEGIN 

     END 
     RETURN @Return 

END TRANSACTION... 

Является ли это правильной медианой функцией? Пожалуйста, исправьте меня. Я изучаюSQL Server Median Function

+3

Название говорит SQL сервер тег MySQL – HLGEM

+0

Проходят некоторые V а также проверить, возвращает ли он данные, которые вам нужны. –

ответ

2

median - это значение, которое накапливает 50% значений (50% процентиля). Так что я думаю, что самый простой способ сделать это:

  1. Подсчитайте количество записей (скажем, это число является «п»)
  2. Выберите верхние n/2 записи (если n даже, вокруг него на следующее целочисленное значение), отсортированные по столбцу, в котором содержится значение, для которого вы хотите вычислить медиану. Прочтите самое большое (последнее) значение этого столбца.

Я не совсем знаком с сервером SQL, но в MySQL я хотел бы сделать это следующим образом:

set @n = (select count(*) from yourTable); 
set @med = ceil(@n/2); 
select yourColumn 
from (
    select yourColumn 
    from yourTable 
    order by yourColumn 
    limit @med 
) as a 
order by yourColumn desc 
limit 1; 
+0

Спасибо, сэр за хороший пример. – user2755462

0

Для SQL Server 2005+ вы могли бы попробовать это решение:

DECLARE @MyTable TABLE 
(
    ID INT PRIMARY KEY, 
    Value NUMERIC(9,2) 
); 
INSERT @MyTable (ID, Value) VALUES (1, 10); 
INSERT @MyTable (ID, Value) VALUES (2, 20); 
INSERT @MyTable (ID, Value) VALUES (3, 30); 
INSERT @MyTable (ID, Value) VALUES (4, 40); 

-- Test #1: 4 rows => AVG(20,30) 
SELECT AVG(y.Value) AS Median#1 
FROM 
(
SELECT *, 
     ROW_NUMBER() OVER(ORDER BY x.ID ASC) AS RowNumASC, 
     ROW_NUMBER() OVER(ORDER BY x.ID DESC) AS RowNumDESC 
FROM @MyTable x 
) y 
WHERE y.RowNumASC = y.RowNumDESC 
OR y.RowNumASC + 1 = y.RowNumDESC 
OR y.RowNumASC - 1 = y.RowNumDESC; 
-- End of Test #1 

-- Test #2: 5 rows => AVG(30) 
INSERT @MyTable (ID, Value) VALUES (5, 50); 
SELECT AVG(y.Value) AS Median#2 
FROM 
(
SELECT *, 
     ROW_NUMBER() OVER(ORDER BY x.ID ASC) AS RowNumASC, 
     ROW_NUMBER() OVER(ORDER BY x.ID DESC) AS RowNumDESC 
FROM @MyTable x 
) y 
WHERE y.RowNumASC = y.RowNumDESC 
OR y.RowNumASC + 1 = y.RowNumDESC 
OR y.RowNumASC - 1 = y.RowNumDESC; 
-- End of Test #2 

Результаты:

Median#1 
--------- 
25.000000 

Median#2 
--------- 
30.000000 
+0

Спасибо. Но я не понимаю, как получить значение ave, используя две таблицы? – user2755462

+0

@ user2755462: Одно из простых решений заключается в замене источника данных FROM FROM MyTable на производную таблицу: 'FROM (SELECT ... FROM JOIN B ...) x'. –