Oracle带ORDER BY的子查询报错:ORA-00907缺失右括号
解决Oracle ORA-00907: missing right parenthesis错误(带ORDER BY的标量子查询问题)
这个问题我之前也踩过坑,Oracle对**标量子查询(嵌入在SELECT列表中的子查询)**的语法有严格限制,直接在里面加ORDER BY会导致解析器报错,哪怕你用rownum<2限制了行数也不行。
错误原因分析
单独执行子查询时没问题,是因为独立查询允许带ORDER BY;但当它作为标量值嵌入主查询的SELECT列表时,Oracle的语法规则不允许直接在这个层级写ORDER BY——解析器会把这个结构判定为语法错误,从而抛出ORA-00907。而且更关键的是,即便不加语法错误,直接写rownum<2再ORDER BY,逻辑也是错的:Oracle会先取符合条件的行(rownum<2),再排序,根本达不到你想要的“取最新创建的那条数据”的效果。
两种可行的解决方案
方案1:嵌套子查询先排序,再取首行
把排序逻辑放到内层子查询,先对table1按created降序排好,再在外层子查询里匹配手机号并取第一行:
select ( select t.person_uid from ( select person_uid, CELL_PH_NUM from table1 order by created desc ) t where t.CELL_PH_NUM = table2.CELL_PH_NUM and rownum < 2 ) from temp table2 ;
这样内层子查询先完成排序,外层子查询再基于排序后的结果匹配手机号并取首行,既符合Oracle语法,又满足你“取最新数据”的需求。
方案2:使用ROW_NUMBER()分析函数(更推荐)
这种写法逻辑更清晰,性能也更稳定,尤其适合数据量较大的场景:
select t1.person_uid from temp table2 left join ( select person_uid, CELL_PH_NUM, row_number() over (partition by CELL_PH_NUM order by created desc) rn from table1 ) t1 on t1.CELL_PH_NUM = table2.CELL_PH_NUM and t1.rn = 1;
通过partition by CELL_PH_NUM按手机号分组,order by created desc给每组内的数据按创建时间降序编号,然后取编号为1的行(也就是每组最新的那条数据),再和table2关联,完美实现需求。
内容的提问来源于stack exchange,提问作者Davide Scicolone
相关产品推荐
相关产品推荐

