ORA-00907: 缺少右括号,可能是子查询有问题

Posted

技术标签:

【中文标题】ORA-00907: 缺少右括号,可能是子查询有问题【英文标题】:ORA-00907: Missing right parenthesis ,maybe problem with SubQuery 【发布时间】:2019-05-19 08:30:43 【问题描述】:

这个查询报错

ORA-00907:缺少右括号

我找不到任何括号问题

   select 
    (select PRE_DESIG_ID FROM AUTHORIZATION 
         WHERE PROJECT_ID = 5 and PRE_DESIG_ID =48 and 
    ROWNUM=1 order by ID DESC) AS PERPARED_BY
    ,(Select PRE_LAST_DATE From (Select PRE_LAST_DATE From AUTHORIZATION  
    Where PROJECT_ID = 5 and PRE_DESIG_ID = 48 Order By ID Desc) 
    Where ROWNUM = 1) AS PRE_END_DT from AUTHORIZATION au
    LEFT join PROJECT p on AU.PROJECT_ID =p.PROJECT_ID
    LEFT join DESIGNATION d on au.AU_DESIG_ID=d.DESIGID;

【问题讨论】:

【参考方案1】:

你的问题是这样的:

ORDER BY id DESC

您不能在充当列表达式的子查询中使用ORDER BY。如果您删除它,您所面临的错误就会消失。

但是,我希望您使用 with 子句重写您的查询,因为您的两个子查询表达式都获取同一行。

WITH auth AS ( SELECT *
                 FROM ( SELECT pre_desig_id AS perpared_by,
                    pre_last_date AS pre_end_dt
                        FROM authorization
                      WHERE project_id = 5
          AND pre_desig_id = 48 ORDER BY id DESC )
 WHERE ROWNUM = 1 )
SELECT a.perpared_by,a.pre_end_dt
  FROM authorization au
  LEFT JOIN project p ON au.project_id = p.project_id
  LEFT JOIN designation d ON au.au_desig_id = d.desigid
 CROSS JOIN auth a;

【讨论】:

对于 12.1 或更高版本的用户,fetch first row only 可以消除很多这种复杂情况。【参考方案2】:

您需要将派生列的 (prepared_by) 子查询转换为类似于 pre_end_dt 的子查询,如下所示

Select 
       (Select pre_desig_id
          From (Select pre_desig_id,
                       row_number() over (order by ID desc) as rn
                  From Authorization
                 Where project_id = 5
                   and pre_desig_id = 48
                 )
         Where rn = 1)  as prepared_by,
       (Select pre_last_date
          From (Select pre_last_date,
                       row_number() over (order by ID desc) as rn
                  From Authorization
                 Where project_id = 5
                   and pre_desig_id = 48
                 )
         Where rn = 1) as pre_end_dt
  From Authorization au
  Left Join Project p
    on au.project_id = p.project_id
  Left Join Designation d
    on au.au_desig_id = d.desigid;

其中Order By ID Desc 部分产生错误,应该包含在额外的子查询中,否则编译器不允许直接使用Order By。即限制(rownum=1)和使用order by不允许在同一级别工作,它们需要分别存在于外部和内部选择语句中。

实际上,最好使用row_number()窗口解析函数而不是rownum伪列,因为它是在排序之前生成的,因此在大多数情况下是不可信的。

即使使用Where rownum = 1order by ID desc 进行内部选择语句也足够你使用,而是养成使用row_number() 函数的习惯。

【讨论】:

以上是关于ORA-00907: 缺少右括号,可能是子查询有问题的主要内容,如果未能解决你的问题,请参考以下文章

ORA-00907: 缺少右括号 00907. 00000 - “缺少右括号” *原因:*操作:行错误:44 列:30

获取 ORA-00907 的 Oracle 查询:缺少右括号

ORDER BY 与内部查询,给出 ORA-00907 缺少右括号

ORA-00907: 缺少右括号

ORA-00907: 两个子查询的左连接缺少右括号

错误:ORA-00907:oracle 缺少右括号