You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MySQL中用CASE WHEN计算中位数?以station表LAT_N列为例

用CASE WHEN在MySQL中计算LAT_N列的中位数

嘿,我来帮你搞定这个需求!MySQL本身没有内置的中位数函数,但我们可以结合排序、定位逻辑,用CASE WHEN来区分总行数奇偶的不同场景,精准算出station表LAT_N列的中位数。

核心思路

  1. 先给LAT_N列排序,给每一行分配一个唯一序号;
  2. 获取总行数,判断奇偶性:
    • 奇数行时,中位数就是排序后正中间那一行的LAT_N值;
    • 偶数行时,中位数是中间两行LAT_N值的平均值;
  3. 用CASE WHEN分支处理这两种情况,输出最终结果。

完整SQL代码(MySQL 8.0+ 支持窗口函数版本)

WITH ranked_lat AS (
    SELECT 
        LAT_N,
        -- 按LAT_N排序,给每行分配序号
        ROW_NUMBER() OVER (ORDER BY LAT_N) AS row_num,
        -- 一次性获取总行数
        COUNT(*) OVER () AS total_rows
    FROM station
)
SELECT
    CASE
        -- 总行数为奇数时,取中间位置的数值
        WHEN total_rows % 2 = 1 THEN
            (SELECT LAT_N FROM ranked_lat WHERE row_num = (total_rows + 1) / 2)
        -- 总行数为偶数时,取中间两个数的平均值
        ELSE
            (SELECT AVG(LAT_N) FROM ranked_lat WHERE row_num IN (total_rows / 2, total_rows / 2 + 1))
    END AS median_lat_n
FROM ranked_lat
LIMIT 1; -- 只返回一行结果即可

低版本MySQL兼容方案(无CTE支持时)

如果你的MySQL版本低于8.0,不支持WITH语句,可以改用子查询实现:

SELECT
    CASE
        WHEN total_rows % 2 = 1 THEN
            (SELECT LAT_N FROM (
                SELECT LAT_N, ROW_NUMBER() OVER (ORDER BY LAT_N) AS row_num
                FROM station
            ) AS ranked WHERE row_num = (total_rows + 1) / 2)
        ELSE
            (SELECT AVG(LAT_N) FROM (
                SELECT LAT_N, ROW_NUMBER() OVER (ORDER BY LAT_N) AS row_num
                FROM station
            ) AS ranked WHERE row_num IN (total_rows / 2, total_rows / 2 + 1))
    END AS median_lat_n
FROM (SELECT COUNT(*) AS total_rows FROM station) AS total;

代码说明

  • ROW_NUMBER() OVER (ORDER BY LAT_N):给排序后的LAT_N每行分配唯一序号,确保我们能精准定位中间行;
  • COUNT(*) OVER ():一次性获取整个表的总行数,避免重复查询表提升效率;
  • CASE WHEN分支:根据总行数的奇偶性,自动匹配对应的中位数计算逻辑;
  • 子查询/CTE的作用:先完成排序和计数的预处理,再在CASE WHEN中快速定位目标行。

这样就能准确算出LAT_N列的中位数啦~

内容的提问来源于stack exchange,提问作者joey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:17:02