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

时间:2013-09-30 14:54:39

标签: sql oracle alias decode

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

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语句中使用了别名,所以我很困惑为什么我收到错误。在这种情况下,它的工作方式是否有所不同?

2 个答案:

答案 0 :(得分:5)

From the documentation(强调补充):

  

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

所以你不能引用where子句中的别名,你现在在哪里:

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

该别名在该点无效,因此它在其中一个表中查找具有该名称的列,但未找到一个。虽然在order by中很好。

您需要使用重复的decode语句替换别名,或者可能使用子查询,然后引用外部查询中的where子句中的别名,但这可能最终会出现效率低,取决于你的其他条件的选择性。

答案 1 :(得分:4)

Oracle按以下顺序运行select查询:

  1. FROM clause
  2. WHERE子句
  3. GROUP BY子句
  4. HAVING条款
  5. SELECT条款
  6. ORDER BY子句
  7. 基于以上所述,您可以看到当您在WHERE部分时,尚未创建别名。如果您想使用SELECT部分​​的结果,可以通过修改查询来实现:

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

    这样,当您到达WHERE部分时,您已经拥有了别名。

    希望这有帮助! :)