Функция PHP для поиска медианы столбца в MySQL

У меня есть база данных, db и в ней таблица Table.

Это выглядит примерно так:

id | val
--------
1 | 45
2 | 35
3 | 23
4 | 49
5 | 67
6 | 12
7 | 0
8 | 87
9 | 46

(Это всего лишь примерный набор данных. Фактический набор данных огромен. И мне нужно работать как можно меньше времени.)

Мне нужно найти медиану столбца val. На самом деле мне нужна функция php, которая будет использоваться несколько раз.

Аналогичный вопрос существует: простой способ вычисления медианы с MySQL

Я попробовал несколько ответов в этом вопросе, никто из них не работал для меня. Принятый ответ не работает, поскольку он использовался только для старой версии SQL.

PS: Он также должен работать в случае многих дубликатов.

1 ответ

просто для удовольствия я думал, что я пытаюсь сделать все это в MySQL, вот sqlFiddle

SELECT 
 CASE 
 WHEN MOD((select count(*) as count from t),2)=1 THEN
 (select val from
 (select @row:=@row+1 as row,val
 from t,(select @row:=0)r
 order by val)t1
 where t1.row = CEIL((select count(*) as count from t)/2)
 )
 ELSE
 ((select val from
 (select @row:=@row+1 as row,val
 from t,(select @row:=0)r
 order by val)t1
 where t1.row = (select count(*) as count from t)/2)+
 (select val from
 (select @row:=@row+1 as row,val
 from t,(select @row:=0)r
 order by val)t1
 where t1.row = ((select count(*) as count from t)/2)+1))/2 
 END AS median

Просто замените вхождения t именем вашей таблицы, не изменяйте t1. Также, если таблица не имеет строк, она возвращает NULL как медиану.

Этот запрос может быть дополнительно сведен ниже (sqlFiddle)

SELECT @rowCount:=(select count(*) as count from t) AS rowcount,
 (select AVG(val) from
 (select @row:=@row+1 as row,val
 from t,(select @row:=0)r
 order by val)t1
 where t1.row IN (FLOOR((@rowCount+1)/2),
 CEIL((@rowCount+1)/2)
 )
 ) as Median

Это будет возвращать 2 колонки, а rowcount столбец и median столбец. Я поставил столбец rowcount потому что я не хотел считать от t несколько раз, как предыдущий запрос.

licensed under cc by-sa 3.0 with attribution.