使用ROW_NUMBER与UNION的HackerRank SQL查询语法错误求助
排查你的SQL语法错误并修正
首先看你遇到的ERROR 1064,最直接的原因是外层查询和子查询之间缺少了FROM关键字,这导致MySQL无法正确解析查询结构。除此之外,你的窗口函数使用也有一些小问题,我来一步步帮你修正:
主要错误点分析
- 缺少
FROM关键字:在SELECT q1.city,q1.charsize之后,必须加上FROM才能引入后面的子查询别名q1,第二个UNION分支的SELECT q2.city,q2.charsize后也存在同样问题。 - 窗口函数引用别名问题:MySQL中,窗口函数的
PARTITION BY/ORDER BY不能直接引用同级别SELECT里定义的别名(比如你这里的charsize),需要用原始表达式替代。 - 不必要的分区字段:
PARTITION BY charsize,city其实不需要按city分区,我们的目标是按城市名称长度分组,在每个长度组内按城市名排序取第一个结果。
修正后的SQL查询
-- 查找最短名称的城市(长度相同则取字典序第一个) SELECT city, charsize FROM ( SELECT city, LENGTH(city) AS charsize, ROW_NUMBER() OVER (PARTITION BY LENGTH(city) ORDER BY city) AS rowno FROM station ) q1 WHERE q1.rowno = 1 UNION -- 查找最长名称的城市(长度相同则取字典序第一个) SELECT city, charsize FROM ( SELECT city, LENGTH(city) AS charsize, ROW_NUMBER() OVER (PARTITION BY LENGTH(city) ORDER BY city) AS rowno FROM station ) q2 WHERE q2.rowno = 1;
额外优化建议
如果想简化查询,也可以用一个子查询同时处理最短和最长长度的筛选,避免重复写子查询:
SELECT city, charsize FROM ( SELECT city, LENGTH(city) AS charsize, ROW_NUMBER() OVER (PARTITION BY LENGTH(city) ORDER BY city) AS rowno, MIN(LENGTH(city)) OVER () AS min_len, MAX(LENGTH(city)) OVER () AS max_len FROM station ) q WHERE rowno = 1 AND (charsize = min_len OR charsize = max_len);
这个优化后的查询只扫描一次station表,通过窗口函数计算全局的最短和最长长度,然后筛选出符合条件的结果,效率更高。
内容的提问来源于stack exchange,提问作者F. Leone
相关产品推荐
相关产品推荐

