-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 回答