-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...

これは正しい中央値関数ですか? 私を修正してください..私は学んでいます

4

2 に答える 2

2

中央値は、値の50% を累積した値 (50% パーセンタイル) です。だから私はそれを行う最も簡単な方法は次のとおりだと思います:

  1. レコードの数を数えます (この数が「n」であるとしましょう)
  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;
于 2013-10-25T21:19:09.123 に答える
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
于 2013-10-25T21:32:11.727 に答える