ORA-00904 - 无效的标识符

Posted

技术标签:

【中文标题】ORA-00904 - 无效的标识符【英文标题】:ORA-00904 - Invalid Identifier 【发布时间】:2016-03-23 14:50:29 【问题描述】:

我是 PL/SQL 的新手,我正在努力尽可能快地学习它。 我试图做一个简单的 SELECT 但我遇到了这个错误。 虽然知道是什么意思,但是真的不知道怎么解决问题... 这是我的部分代码:

SELECT
    NVL(UPPER(T.COL1),'N.D.') COL1,
    V.SECO,
    'N' CL_MED,
    V.DEST_USO,
  (CASE  
    WHEN V.COL2 IS NULL
        AND V.SECO IN ('B090','B100') THEN ''
    WHEN V.COL2 LIKE 'L-DEF%' 
        OR V.COL2 LIKE 'L-FUI%' 
        AND V.SECO IN ('B090','B100') THEN 'FUI/DEF'
    WHEN V.COL2 IS NULL 
        AND V.SECO = 'B080' 
        AND V.COL3 LIKE 'DEF%'
        OR V.COL3 LIKE 'FUI%' THEN 'FUI/DEF'  
    ELSE ''
    END 
    ) FLAG_DEF_FUI
  FROM TAB1 V
  JOIN TAB2 C ON (V.COL4    = C.COL4
                 AND V.COL5       = C.COL5
                 AND V.COL6 = C.COL6)
  JOIN TAB3 T ON (V.COL4  = T.COL4
                  AND V.COL5 = T.COL5
                  AND V.COL5A = T.COL5A
                  AND T.COL6 =V.COL6)
  WHERE V.COL4 = :COL4
  AND V.COL6 = :COL6
  AND V.COL5 NOT IN
    (SELECT gcm.PDR
    FROM TAB4 gcm
    WHERE gcm.COL6 = :COL6
    )
  GROUP BY (UPPER(T.COL1),V.SECO, V.DEST_USO, FLAG_DEF_FUI)    

并且 FLAG_DEF_FUI 是导致此错误的列.....有帮助吗?!

编辑:我不是在问为什么我不能在 GROUP BY 中使用别名。我正在寻求解决此问题的方法...

【问题讨论】:

Why doesn't Oracle SQL allow us to use column aliases in GROUP BY clauses?的可能重复 是正确的'N' CL_MED 还是类似'N'+''+ CL_MED 在select statemnt 中 @piet.t 我知道别名不能在 group by 中使用。我只是在询问有关如何编辑查询以使其工作的建议... 使用链接问题的答案中建议的子查询(内联视图)。或者如果您已经知道原因,this question 可能是更好的副本? 等等,你为什么有一个 group-by 子句呢?您没有使用任何聚合函数。你只是得到重复?如果是这样,请改用distinct 【参考方案1】:

为了对您拥有的复杂功能进行分组,我总是进行子选择。因此,您的查询将变为:

  select child_query.stuff, child_query.flag_def_fui
    from 
   (   
    select
        'some-stuff' some_stuff,
      (case  
        when v.col2 is null
            and v.seco in ('b090','b100') then ''
        when v.col2 like 'l-def%' 
            or v.col2 like 'l-fui%' 
            and v.seco in ('b090','b100') then 'fui/def'
        when v.col2 is null 
            and v.seco = 'b080' 
            and v.col3 like 'def%'
            or v.col3 like 'fui%' then 'fui/def'  
        else ''
        end 
        ) flag_def_fui
      from tab1 v
      join tab2 c
      on (v.col4    = c.col4
      and v.col5       = c.col5
      and v.col6 = c.col6)
      join tab3 t
      on (v.col4            = t.col4
      and v.col5               = t.col5
      and v.col5a              = t.col5a
      and t.col6         =v.col6)
      where v.col4          = :col4
      and v.col6         = :col6
      and v.col5 not          in
        (select gcm.pdr
        from tab4 gcm
        where gcm.col6 = :col6
        )
     )  child_query 
      group by child_query.stuff, child_query.flag_def_fui;

【讨论】:

但它是按选择列表中的每一列进行分组的——那么为什么不直接使用 distinct 呢? 不,问题是我已经删除了所有对示例不感兴趣的列,以便于阅读。您可以添加所需的每一列,并且选择也将按预期工作 不确定你的意思。这包含问题中的所有列。您添加到选择列表的任何列也必须添加到分组依据,除非它们是聚合。如果没有任何聚合,为什么可以使用 distinct 进行分组? 在我给出的解决方案中,我删除了列 NVL(UPPER(T.COL1),'N.D.') COL1, V.SECO, 'N' CL_MED, V.DEST_USO... .为了更好的理解,但似乎我失败了。【参考方案2】:

其他答案为您提供了两个选择,并且都是正确的。为了清楚起见,并专门回答您编辑的问题,您有三个选项可以解决无法引用 GROUP BY 中的别名列的问题:

1) Answer 1: Wrap your query 以便可以轻松引用列别名,即

  SELECT column_alias 
    FROM (<your query>) 
GROUP BY column_alias;

2) Answer 2: Don't use GROUP BY 如果您不使用聚合函数,请改用DISTINCT

3) 将构成列的复杂表达式复制到GROUP BY,即

  SELECT CASE  
           WHEN col1 = 1 THEN 'one'
           WHEN col1 = 2 THEN 'two'
           ELSE ''
         END as col1_alias,
         SUM(col2) as col2_alias,
         col3
    FROM table_name
GROUP BY CASE  
           WHEN col1 = 1 THEN 'one'
           WHEN col1 = 2 THEN 'two'
           ELSE ''
         END,
         col3;

【讨论】:

【参考方案3】:

从您所展示的内容来看,您根本不需要 group-by 子句,因为您没有聚合函数(最小值、最大值等)。选择列表中的每一列都在 group-by 子句中。

如果您使用该子句来抑制重复,那么使用 distinct 关键字会更简单:

SELECT DISTINCT
    NVL(UPPER(T.COL1),'N.D.') COL1,
    V.SECO,
    'N' CL_MED,
    V.DEST_USO,
  (CASE  
    WHEN V.COL2 IS NULL
        AND V.SECO IN ('B090','B100') THEN ''
    WHEN V.COL2 LIKE 'L-DEF%' 
        OR V.COL2 LIKE 'L-FUI%' 
        AND V.SECO IN ('B090','B100') THEN 'FUI/DEF'
    WHEN V.COL2 IS NULL 
        AND V.SECO = 'B080' 
        AND V.COL3 LIKE 'DEF%'
        OR V.COL3 LIKE 'FUI%' THEN 'FUI/DEF'  
    ELSE ''
    END 
    ) FLAG_DEF_FUI
  FROM TAB1 V
  JOIN TAB2 C
  ON (V.COL4    = C.COL4
  AND V.COL5       = C.COL5
  AND V.COL6 = C.COL6)
  JOIN TAB3 T
  ON (V.COL4            = T.COL4
  AND V.COL5               = T.COL5
  AND V.COL5A              = T.COL5A
  AND T.COL6         =V.COL6)
  WHERE V.COL4          = :COL4
  AND V.COL6         = :COL6
  AND V.COL5 NOT          IN
    (SELECT gcm.PDR
    FROM TAB4 gcm
    WHERE gcm.COL6 = :COL6
    )

(您可能还想看看not exists 检查是否会比您现在拥有的not in 更有效。)

【讨论】:

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

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

ORA-00904 无效标识符错误

为啥我会收到:[Oracle][ODBC][Ora]ORA-00904:标识符无效

SQL 错误 ORA-00904:标识符无效

ORA-00904 标识符无效

ORA-00904: "FORMAT": 无效标识符