Oracle中未分组聚合查询改写后执行成功,是否符合规范?
问题解答
核心结论
你改写后的SQL语法上在Oracle中是合规的,但逻辑完全错误,属于依赖Oracle非标准特性的写法,不建议使用。
具体分析
原SQL报错原因
原语句select data,count(*) from table_a触发ORA-00937,是因为SQL标准要求:当SELECT列表中同时包含非聚合列(比如data)和聚合函数(比如count(*))时,非聚合列必须出现在GROUP BY子句中,否则数据库无法确定要返回哪一行的data值。改写后SQL的执行逻辑
你改写的语句:select sum from (select data,count(*) as sum from table_a)- 为什么能执行?Oracle允许这种不符合SQL标准的写法:当子查询中同时选取非聚合列和聚合函数却没有
GROUP BY时,Oracle会将整个表视为一个分组,此时非聚合列data会随机返回表中某一行的取值(类似使用ANY_VALUE(data)函数的效果)。 - 你外层只取了
sum,所以看起来执行成功,但这个sum其实就是整个表的总行数,和直接写select count(*) from table_a结果一致。但子查询里的data是无意义的随机值,只是你没用到它而已。
- 为什么能执行?Oracle允许这种不符合SQL标准的写法:当子查询中同时选取非聚合列和聚合函数却没有
合规性与风险
- 语法上:Oracle当前版本允许这种写法,属于语法合规,但不符合ANSI SQL标准。
- 逻辑上:完全错误,因为子查询的
data取值随机,且写法依赖Oracle的非标准行为,一旦迁移到其他数据库(比如PostgreSQL、开启ONLY_FULL_GROUP_BY的MySQL),或者Oracle后续版本收紧语法检查,这个语句会直接报错。
内容的提问来源于stack exchange,提问作者ANTHONY
相关产品推荐
相关产品推荐

