Hackerrank Weather Observation Station 20:求纬度中位数SQL语句报错求助
问题分析与修正
你的SQL存在三个核心问题:
- WHERE子句中无法直接使用聚合函数
count(*):count(*)是聚合函数,会在所有行过滤完成后计算,WHERE子句执行时还没有聚合结果,因此会直接报错。 - 中位数逻辑不完整:只处理了总行数为偶数时的其中一个中间行,既没覆盖奇数行的情况(此时中位数是中间唯一的行),也没考虑偶数行需要取两个中间值的平均值(这是中位数的标准定义)。
- ROW_NUMBER()的局限性:如果存在重复的
lat_n值,ROW_NUMBER()会给相同值分配不同的序号,可能导致中间行选取不准确,无法正确反映重复值对中位数的影响。
修正后的SQL写法
以下是适配Hackerrank题目要求的正确写法,同时处理奇数/偶数行数的情况:
WITH station_ranked AS ( SELECT lat_n, -- 生成按lat_n排序的行号 ROW_NUMBER() OVER(ORDER BY lat_n) AS row_num, -- 计算总行数(窗口函数直接获取,无需单独聚合) COUNT(*) OVER() AS total_count FROM station ) SELECT -- 奇数行取中间单行,偶数行取中间两行的平均值 CASE WHEN total_count % 2 = 1 THEN lat_n ELSE (SELECT AVG(lat_n) FROM station_ranked WHERE row_num IN (total_count/2, total_count/2 + 1)) END AS median_lat_n FROM station_ranked -- 定位到中间行(奇数行的中间位置,偶数行的上中间位置) WHERE row_num = CEIL(total_count / 2) LIMIT 1;
简化版写法(针对Hackerrank测试用例)
如果题目允许使用更简洁的窗口函数逻辑,也可以用PERCENT_RANK来匹配中位数区间:
SELECT AVG(lat_n) AS median_lat_n FROM ( SELECT lat_n, PERCENT_RANK() OVER(ORDER BY lat_n) AS p_rank FROM station ) ranked -- 匹配中位数所在的百分比区间(兼容奇偶行数) WHERE p_rank >= 0.5 - 1e-9 AND p_rank <= 0.5 + 1e-9;
内容的提问来源于stack exchange,提问作者shivansh rastogi
相关产品推荐
相关产品推荐

