MySQL 8中ROUND()配合OVER子句使用报错如何解决
问题产生原因
这个报错和Sales字段的Double类型、ROUND/CAST/CONVERT函数本身的功能无关,是MySQL 8解析器的语法匹配规则导致的:
- 只有原生支持窗口语法的函数(聚合函数SUM/COUNT/AVG、专用窗口函数ROW_NUMBER/RANK等)可以直接后接
OVER(...)子句 - 你之前的错误写法是把
OVER(...)子句放在了ROUND函数的外层,即写成ROUND(SUM(Sales),2) OVER(...),此时解析器会判定OVER跟随的是ROUND函数,而ROUND不是窗口函数,无法识别这个语法位置,直接抛出OVER is not valid at this position错误。 - 不带OVER子句的普通GROUP BY聚合场景下,SUM(Sales)会直接返回分组后的单值,不存在OVER子句归属的语法匹配问题,因此
ROUND(SUM(Sales),2)可以正常执行。
正确修改方式
将OVER(...)子句紧贴在内层的SUM聚合函数之后,先让SUM完成窗口分区的聚合计算,再把聚合结果传入ROUND做小数位截断即可,语法格式为ROUND( SUM(计算字段) OVER(窗口分区/排序规则), 保留小数位数 )。
修正后的完整可运行代码如下:
SELECT row_number() OVER (PARTITION BY Region ORDER BY Category, Sales) as Row_No, Name as Product, Category, Sales, ROUND(SUM(Sales) OVER (PARTITION BY Region, Category), 2) as Category_Sales, ROUND(SUM(Sales) OVER (PARTITION BY Region), 2) as Regional_Sales FROM `table` WHERE Region = "North" ORDER BY Category, Sales;
注:原语句中
row_number() OVER (PARTITION BY Region)没有指定分区内排序规则,同分区下返回的行号是随机不稳定的,建议补充和最终排序一致的ORDER BY规则,保证查询结果确定性。另外table是SQL保留字,作为表名使用时建议用反引号包裹,避免潜在语法冲突。
内容的提问来源于stack exchange,提问作者Sachin D
相关产品推荐
相关产品推荐

