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

MySQL中时间类型列的精确中位数获取及结果取整问题

问题分析与解决方案

为什么结果被取整?

你的查询结果被取整的核心原因是时间转换过程中丢失了小数精度:

  • TIME_TO_SEC(ride_time)会将TIME类型值转换为整数秒数,直接丢弃TIME字段中存储的毫秒/微秒部分。
  • 当你对这些整数秒取平均值后,即使结果带有小数(比如8.5秒),SEC_TO_TIME()函数会自动截断小数部分,只保留整数秒,最终呈现为整分钟的时间值(如00:08:00.0000)。

如何获取精确的中位数?

方法1:保留微秒精度重新计算

将TIME类型转换为包含微秒的精确数值,计算平均后再转回TIME类型,完整保留小数精度:

WITH RankedRides AS (
  SELECT
    ride_time,
    ROW_NUMBER() OVER (ORDER BY ride_time) AS row_num,
    COUNT(*) OVER () AS total_rows
  FROM
    q4_2022_data
)
SELECT
  SEC_TO_TIME(
    AVG(
      TIME_TO_SEC(ride_time) + MICROSECOND(ride_time) / 1000000
    )
  ) AS median_ride_time
FROM RankedRides
WHERE
  row_num BETWEEN (total_rows DIV 2) + 1 AND (total_rows DIV 2) + 2;

这里通过MICROSECOND(ride_time)/1000000把微秒转换为秒的小数部分,和整数秒合并后计算平均值,再转回TIME类型,就能保留完整的精度。

方法2:使用PERCENTILE_CONT函数(MySQL 8.0+)

如果你使用的是MySQL 8.0及以上版本,更推荐用PERCENTILE_CONT(连续百分位数函数)直接计算,它会返回精确的中位数(偶数条记录时自动取中间两个值的平均),无需手动排序分组:

SELECT
  SEC_TO_TIME(
    PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY 
      TIME_TO_SEC(ride_time) + MICROSECOND(ride_time)/1000000
    )
  ) AS median_ride_time
FROM q4_2022_data;

补充:你之前尝试的PERCENTILE_DISC是离散百分位数函数,它只会返回表中实际存在的某条记录的ride_time值,不会计算平均值,这也是它没达到你预期的原因。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 11:42:47