Проблема с предлагаемым решением (TheJacobTaylor) - это время выполнения. Присоединение стола к себе медленнее, как меласса для больших наборов данных. Мой предлагаемый альтернативный запуск в mysql, имеет потрясающее время выполнения, использует явный оператор ORDER BY, поэтому вам не нужно надеяться, что ваши индексы упорядочили его правильно, чтобы дать правильный результат, и легко развернуть запрос для отладки.
SELECT avg(t1.val) as median_val FROM (
SELECT @rownum:=@rownum+1 as `row_number`, d.val
FROM data d, (SELECT @rownum:=0) r
WHERE 1
-- put some where clause here
ORDER BY d.val
) as t1,
(
SELECT count(*) as total_rows
FROM data d
WHERE 1
-- put same where clause here
) as t2
WHERE 1
AND t1.row_number in ( floor((total_rows+1)/2), floor((total_rows+2)/2) );
[edit] Добавлена функция avg () вокруг t1.val и row_number в (...), чтобы правильно создать медиану, когда есть четное количество записей. Рассуждение:
SELECT floor((3+1)/2),floor((3+2)/2);#total_rows is 3, so avg row_numbers 2 and 2
SELECT floor((4+1)/2),floor((4+2)/2);#total_rows is 4, so avg row_numbers 2 and 3