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...
这是正确的中位函数吗?请纠正我..我正在学习
答案 0 :(得分:2)
中位数是累积50%值(50%百分位数)的值。所以我认为最简单的方法是:
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;
答案 1 :(得分: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