2

I'm trying to count median for prices. I founded answer how to do it here- Simple way to calculate median with MySQL, but it doesn't work for me, I get empty result. Can anyone help?

SELECT x.price from mediana as x, mediana y
GROUP BY x.price
HAVING SUM(SIGN(1-SIGN(y.price-x.price))) = (COUNT(*)+1)/2
Community
  • 1
  • 1
Alex
  • 479
  • 1
  • 8
  • 19
  • Can you demonstrate this with a sqlfiddle? – Ja͢ck Mar 11 '13 at 12:32
  • http://sqlfiddle.com/#!2/b3fe7e/1 – Alex Mar 11 '13 at 12:44
  • @defaultlocale, thanks, it works, but a little bit not as I expected. If I have price - 1,2,3,4 median should be 2.5, but I get 3 – Alex Mar 11 '13 at 13:00
  • @AlexK Yes it doesn't handle even number of records (mean of 2 middle elements). Try [this](http://sqlfiddle.com/#!2/b3fe7e/22) I haven't tested it, though. – default locale Mar 11 '13 at 13:11
  • Thank you very much! Saved me! ;) – Alex Mar 11 '13 at 13:16
  • @AlexK You're welcome. I decided to post it as an answer here. Check it out. – default locale Mar 11 '13 at 13:19
  • @defaultlocale, hi! Maybe you can help me second time..I need to get median value not for all table, but grouped by date. Is it possible? http://sqlfiddle.com/#!2/7cf27 - so as result I will get 2013-03-06 - 1.5 , 2013-03-05 - 3.5. – Alex Mar 13 '13 at 13:06

1 Answers1

3

AFAIU your question.

This answer by @velcrow calculates median value successfully. Unfortunately when there is even number of rows instead of calculating the mean value of 2 middle rows query just returns second value. I've made a couple of modifications to the query to fit your needs:

--average value for middle rows
SELECT avg(t1.price) as median_val FROM (
SELECT @rownum:=@rownum+1 as `row_number`, d.price
  FROM mediana d,  (SELECT @rownum:=0) r
  WHERE 1
  -- put some where clause here
  ORDER BY d.price
) as t1, 
(
  SELECT count(*) as total_rows
  FROM mediana d
  WHERE 1
  -- put same where clause here
) as t2
WHERE 1
--this condition should return one record for odd number of rows and 2 middle records for even.
AND t1.row_number>=total_rows/2 and t1.row_number<=total_rows/2+1; 

Test on sample data on sqlfiddle

Community
  • 1
  • 1
default locale
  • 11,849
  • 13
  • 52
  • 59