如何在MySQL的OFFSET中使用子查询?求中位数SQL报错求助
修正HackerRank中位数计算的SQL问题
你的SQL代码存在两个核心问题:
- OFFSET参数类型错误:子查询中
COUNT(LAT_N) / 2会返回浮点数(例如总数为5时结果为2.5),但OFFSET仅接受整数,这直接导致语法或运行时错误。 - 中位数逻辑不符合要求:当数据量为偶数时,中位数应为中间两个数的平均值,但你的代码仅取其中一个数,无法得到正确结果。
推荐解决方案(窗口函数实现)
使用窗口函数可以简洁且准确地处理奇偶两种情况的中位数计算:
WITH ranked_latitudes AS ( SELECT LAT_N, ROW_NUMBER() OVER(ORDER BY LAT_N) AS row_num, COUNT(*) OVER() AS total_count FROM STATION ) SELECT ROUND(AVG(LAT_N), 4) FROM ranked_latitudes WHERE row_num IN ((total_count + 1) // 2, (total_count + 2) // 2);
代码说明
- CTE
ranked_latitudes:为每个纬度值按升序分配行号,同时计算数据总条数。 - 筛选与计算:
- 若总条数为奇数,
(total_count + 1) // 2与(total_count + 2) // 2会得到同一个行号,直接取该位置的数值作为中位数。 - 若总条数为偶数,会选中中间两个行号对应的数值,取其平均值作为中位数。
- 若总条数为奇数,
- 结果格式化:将最终结果四舍五入到4位小数,符合题目要求。
针对原代码的语法修复(仅解决错误,不修正逻辑)
如果仅想修复原代码的语法问题,可将除法改为整数除法(确保OFFSET参数为整数),但此方案仅在数据量为奇数时正确:
SELECT ROUND(LAT_N, 4) FROM STATION ORDER BY LAT_N LIMIT 1 OFFSET ( SELECT CASE WHEN COUNT(LAT_N) % 2 <> 0 THEN COUNT(LAT_N) DIV 2 ELSE (COUNT(LAT_N) - 1) DIV 2 END FROM STATION );
内容的提问来源于stack exchange,提问作者Khushi Mittal
相关产品推荐
相关产品推荐

