在MySQL中计算一列的简单中位数

7

我很难找到一个简单中位数问题的解决方案。给定一个只有一个列的表my_table

my_column | 
----------|
10        |
20        |
30        |
40        |
50        |
60        |

如何调用一个函数返回35的中位数?

当我只想返回中位数时,我无法理解如何让这个语法工作:

SELECT
  PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY my_column) OVER ( PARTITION BY my_column)
FROM
  my_table

35 是平均数,不是中位数。 - Bill Karwin
3
@BillKarwin 这完全不正确。由于数据集中的值数量为偶数,因此不存在单个中位数。结果,统计学家通常会报告30和40的平均值作为中位数。在这种情况下,中位数是35,巧合的是它也是平均值。 - Tim Biegeleisen
2
我明白了,我撤回我的评论。 :) - Bill Karwin
1
抱歉,我应该使用更好的示例数据以保持更清晰! - Tom Rossi
撤回评论的一种方法是将其删除。 - Strawberry
由于您标记了Mariadb:Mariadb 10.2具有类似于MySQL 8的“窗口函数”。 - Rick James
3个回答

5

这是我在 MySQL 8.0 中测试的解决方案:

with ranked as (
  select my_column, 
    row_number() over (order by my_column) as r,
    count(my_column) over () as c 
  from my_table
),
median as (
  select my_column 
  from ranked 
  where r in (floor((c+1)/2), ceil((c+1)/2))
)
select avg(my_column) from median

输出:

+----------------+
| avg(my_column) |
+----------------+
|        35.0000 |
+----------------+

我借鉴了https://dev59.com/SXM_5IYBdhLWcg3wp00X#7263925中的方法,但对其进行了适应以适用于MySQL 8.0的CTE和窗口函数。


1
我会使用带有空的 OVER() 子句的 distinct
SELECT DISTINCT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY my_column) OVER () median
FROM my_table

1
注意:此答案仅适用于MariaDB,不适用于MySQL(PERCENTILE_CONT在MySQL中不存在)。 - bsplosion

0

你可以尝试以下方法:

SELECT col_median
FROM
(
    SELECT PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY my_column) OVER () AS col_median
    FROM my_table
) t
LIMIT 1;

演示

注: PERCENTILE_CONT函数是一个窗口函数,其输出在此情况下仅能在扫描整个列后确定。 因此,上面子查询的输出实际上是您的列,以及一个新列,在所有行中具有相同的中位数值。 但是,由于您只想将中位数报告为单个数字,因此我使用LIMIT 1外部查询来获取该单个中位数值。


太好了!如果我想要得到0.25、0.50、0.75、0.90百分位数,我只需要按照同样的模式吗? - Tom Rossi
对于整个表格,是的,那应该可以(请尝试使用我的演示链接进行操作)。 - Tim Biegeleisen
根据该演示链接,这在MariaDB中可以工作,但不适用于MySQL8.0或更早版本。 - jacobmovingfwd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接