ORA-00904 解码别名上的标识符无效

Posted

技术标签:

【中文标题】ORA-00904 解码别名上的标识符无效【英文标题】:ORA-00904 invalid identifier on decode alias 【发布时间】:2013-09-30 14:54:39 【问题描述】:

当我尝试在我的select 语句中使用decode 的别名时,我遇到了标题中所述的错误。代码如下:

SELECT DISTINCT rl.complaint_date, 
                  decode(rl.judgement_date,null,rl.complaint_amt,rl.judgement_amt) as account_amt, 
                  rl.date_served1, 
                  rl.date_served2,
                  rl.judgement_date,         
                  rl.skip_locate,
                  rl.case_no,
                  lcc.bal_range_min, 
                  lcc.bal_range_max, 
                  lcc.cost_range_min, 
                  lcc.cost_range_max, 
                  lcc.court,
                  lcc.county AS lcc_county,
                  ah.ACCOUNT, 
                  ah.transaction_code, 
                  ah.transaction_date, 
                  ah.rule_id, 
                  ah.amount, 
                  ah.description,                    
                  r.state, 
                  r.zip_code, 
                  z.county AS ah_county,
                  z.county_2,
                  z.county_3,
                  z.county_4
  FROM legal_address_skip las,
       racctrel r, 
       ziplist z, 
       legal_court_cost lcc, 
       racctlgl rl,
       legal_transaction_review ah
  WHERE ah.ACCOUNT = rl.ACCOUNT
  AND ah.ACCOUNT = las.ACCOUNT(+)
  AND ah.ACCOUNT = r.ACCOUNT
  AND nvl(lpad(substr(r.zip_code,0,instr(r.zip_code,'-')-1),5,0), substr(r.zip_code,1,5)) = z.zip 
  AND r.state = lcc.state
  AND (REPLACE(lcc.county,' ','') = REPLACE(upper(z.county),' ','') 
       OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_2),' ','')
       OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_3),' ','')
       OR REPLACE(lcc.county,' ','') = REPLACE(upper(z.county_4),' ',''))
  AND lcc.transaction_code = ah.transaction_code
  AND lcc.transaction_code = 1
  AND lcc.end_date IS NULL
  AND ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max
  AND (account_amt NOT BETWEEN lcc.bal_range_min AND lcc.bal_range_max
      OR lcc.bal_range_min - account_amt NOT BETWEEN 0 AND 500)
  ORDER BY CASE 
           WHEN ah.amount NOT BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 1
           WHEN ah.amount BETWEEN lcc.cost_range_min AND lcc.cost_range_max THEN 2 END, ah.amount;

我以前在 select 语句中使用过别名,所以我很困惑为什么我会因此而出错。在这种情况下它的工作方式会有所不同吗?

【问题讨论】:

查询在 WHERE 子句中使用AND (account_amt NOT BETWEEN 。是否有任何表包含名为 account_amt 的列? 【参考方案1】:

From the documentation(强调):

您可以使用列别名c_alias 来标记立即 选择列表中的前一个表达式,以便该列是 以新标题显示。别名有效地重命名了选择 查询期间的列表项。 别名可用于 ORDER BY 子句,但不是查询中的其他子句。

所以你不能在where 子句中引用别名,此时你有:

...
AND (account_amt NOT BETWEEN ...
...

此时别名无效,因此它正在其中一个表中查找具有该名称的列,但没有找到。不过order by 没问题。

您要么需要用重复的 decode 语句替换别名,要么可能使用子查询,然后在外部查询的 where 子句中引用别名,但这最终可能会降低效率,具体取决于您的其他条件的选择性如何。

【讨论】:

【参考方案2】:

Oracle 按以下顺序运行选择查询:

    FROM 子句 WHERE 子句 GROUP BY 子句 HAVING 子句 SELECT 子句 ORDER BY 子句

根据上面可以看到,当你在WHERE部分的时候,别名还没有被创建。如果您想使用 SELECT 部分的结果,可以通过如下方式修改查询来实现:

WITH q AS 
(
-- Your query without the extra AND
)
SELECT *
FROM q
WHERE --put your check here

这样,当您到达 WHERE 部分时,您就已经可以使用别名了。

希望这会有所帮助! :)

【讨论】:

感谢您的有用提示!

以上是关于ORA-00904 解码别名上的标识符无效的主要内容,如果未能解决你的问题,请参考以下文章

ORA-00904: 无效的标识符,当列标题正确时

python调用oracle函数ORA-00904无效标识符

ORA-00904: 子查询中的无效标识符(在选择子句中)

SQL 错误:ORA-00904:“GENDER”:无效标识符 00904。00000 -“%s:无效标识符”

错误报告:SQL 错误:ORA-00904::无效标识符 00904。00000 - “%s:无效标识符”

ORA-00904: 无效标识符 00904. 00000 - "%s: 无效标识符"