Main Page | Report this Page
Computers Forum Index  »  Computer - Databases - Ingres  »  An elegant query for the weighted median?...
Page 1 of 1    

An elegant query for the weighted median?...

Author Message
--CELKO--...
Posted: Wed Sep 16, 2009 2:46 pm
Guest
Given a table of values and the ROW_NUMBER() function it is pretty
easy to compute the traditional Median. Example:

CREATE TABLE Foobar(x INTEGER NOT NULL);
INSERT INTO Foobar VALUES (1), (2), (2), (3), (3), (3);

The traditional median would be AVG(2, 3) = 2.5. Take the two middle
values and average them. The weighted median would return AVG (2, 2,
3, 3, 3) = 13/5 = 2.6 instead. Take the subsets of the two middle
values so that the results skew in the direction of the most frequent
middle value. Likewise, AVG (2, 2, 2, 3, 3) = 12/5 = 2.4.

The traditional median is pretty easy with ROW_NUMBER(); here are two
ways:

SELECT AVG(x) AS median
FROM (SELECT x,
ROW_NUMBER()
OVER(ORDER BY x) AS row_nbr,
COUNT(*) OVER() AS row_cnt
FROM Foobar)
AS OrderedFoobar
WHERE row_nbr IN((row_cnt + 1)/2, (row_cnt + 2)/2);

or:

SELECT AVG(x) AS median
FROM (SELECT x,
ROW_NUMBER() OVER(ORDER BY x ASC),
ROW_NUMBER() OVER(ORDER BY x DESC)
FROM Foobar)
AS SortedFoobar (x, high, low)
WHERE high IN (low, low+1, low-1);

I have been trying to do a weighted median along the same lines, but I
keep getting ugly code. Anyone see an elegant way to do this with
COUNT(), RANK(), DENSE_RANK() and/ ROW_NUMBER()? I have a feeling it
exists and I am not seeing it.
 
 
Page 1 of 1    
All times are GMT
The time now is Sat Nov 28, 2009 8:50 am