提问人:teghs 提问时间:11/15/2023 更新时间:11/15/2023 访问量:24
在MySQL中查找时间类型列的中位数
Finding the median of a time type column in MySQL
问:
所以我有一个表格q4_2022_data其中每条记录是一次骑自行车,这个表中有一列叫做ride_time是每次骑行的时间。我正在使用 MySQL 并尝试使用 PERCENTILE_DISC 来查找此列的中值,但显然不起作用。
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))
) AS median_ride_time
FROM (
SELECT
ride_time,
row_num,
total_rows
FROM
RankedRides
) AS subquery
WHERE
row_num BETWEEN (total_rows DIV 2) + 1 AND (total_rows DIV 2) + 2;
这是我提出的查询,它给了我一个值 00:08:00.0000,我尝试了其他四分之一表(q1、q2、q3)进行检查,并意识到每个值都是一个整数。我得到了结果 00:10:00.0000, 00:11:00.0000 .我能做些什么来让我得到确切的中位数,谁能弄清楚为什么它被四舍五入。任何帮助都是值得赞赏的,谢谢。
答:
0赞
Adesoji Alu
11/15/2023
#1
您使用 ROW_NUMBER() 和 COUNT(*) 的方法是正确的。我只是觉得你在最终的 SELECT 语句中计算中位数的方式需要调整。此外,中位数计算应根据总行数是偶数还是奇数而有所不同。至少,如果是奇数,中位数是中间值,如果是偶数,则中位数是两个中间值的平均值,我希望我是正确的。现在,获得 00:10:00.0000 等结果的问题描绘了 AVG(TIME_TO_SEC(ride_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))
) AS median_ride_time
FROM (
SELECT
ride_time,
row_num,
total_rows
FROM
RankedRides
) AS subquery
WHERE
(total_rows % 2 = 1 AND row_num = (total_rows + 1) / 2) OR
(total_rows % 2 = 0 AND (row_num = total_rows / 2 OR row_num = total_rows / 2 + 1));
评论
SEC_TO_TIME(AVG(TIME_TO_SEC(ride_time)))