查询在使用联接时抛出ORA-00904无效的标识符

时间:2015-02-02 17:48:26

标签: sql oracle

我遇到了一些奇怪的行为,导致我无法按照我想要的方式设置查询。会欣赏任何想法。如果有关于表格的任何信息有帮助,请告诉我。我看着他们,没有任何东西跳出来,可能会导致这一点,但我也不知道我在寻找什么。这是行为。

这很好用:

Select * 
From 
    SCHEMA_A.TABLE_A a,
    SCHEMA_B.TABLE_B b,
    SCHEMA_C.TABLE_C c,
    SCHEMA_A.TABLE_D d
Where 
    b.friend_id = c.friend_id
    AND a.group_id = d.group_id
    AND b.group_cd = d.group_cd

但是这会返回ORA-00904:b.friend_id = c.friend_id:无效的标识符

Select * 
From 
    SCHEMA_A.TABLE_A a,
    SCHEMA_B.TABLE_B b,
    SCHEMA_A.TABLE_D d
Join 
    SCHEMA_C.TABLE_C c
On
    b.friend_id = c.friend_id
Where 
    a.group_id = d.group_id
    AND b.group_cd = d.group_cd

返回ORA-00904:b.group_cd = d.group_cd:无效标识符

Select * 
From 
    SCHEMA_A.TABLE_A a,
    SCHEMA_B.TABLE_B b
Join 
    SCHEMA_C.TABLE_C c
On
    b.friend_id = c.friend_id
Join 
    SCHEMA_A.TABLE_D d
On 
    a.group_id = d.group_id
    AND b.group_cd = d.group_cd

这又有效了:

Select * 
From 
    SCHEMA_A.TABLE_A a,
    SCHEMA_B.TABLE_B b
Join 
    SCHEMA_C.TABLE_C c
On
    b.friend_id = c.friend_id
Join 
    SCHEMA_A.TABLE_D d
On
    b.group_cd = d.group_cd
Where  
    a.group_id = d.group_id

3 个答案:

答案 0 :(得分:2)

尝试使用专为using设计的join关键字

Select * 
From 
    SCHEMA_A.TABLE_A a,
    SCHEMA_B.TABLE_B b
Join 
    SCHEMA_C.TABLE_C USING(friend_id)
Join 
    SCHEMA_A.TABLE_D d using(group_id)
where b.group_cd = d.group_cd;

还要确保您与合适的用户执行其他查询,因为没有正确权限的用户将抛出invalid identifier

修改:实际问题是您将TABLE_C加入TABLE_D,但加入条件是指TABLE_B将其更改为

Select * 
From 
    SCHEMA_A.TABLE_A a,
    SCHEMA_A.TABLE_D d,
    SCHEMA_B.TABLE_B b
Join 
    SCHEMA_C.TABLE_C c using(friend_id)
Where 
    a.group_id = d.group_id
    AND b.group_cd = d.group_cd;

对其他查询应用相同的逻辑,在进行连接时,不要加入一组表,而是加入from子句中提到的最后一个表,因此它无法访问{{1 }}

对于可能出现TABLE_B错误的其他人,请确保您的数据库不区分大小写,否则请确保使用正确的大小写。

答案 1 :(得分:2)

我相信你已经遇到了处理连接范围/优先级的SQL的复杂性。由于我自己不是数据库程序员,所以我无法告诉你它为什么会这样运行,但我确实看到了查询解析器行为方式的一些逻辑。

在第一个查询中,所有连接都是交叉连接。因此,它们应具有相同的优先权。因此,在评估连接时,所有已连接的列都是已知的。

在第二个查询中,您有交叉联接和内部联接的组合。如果我们假设内连接优先于交叉连接,则在将任何其他表添加到混合之前连接表c和d。因此,当您在内连接中引用b.friend_id时,查询解析器无法使用该列来评估连接。

在第三个查询中,表b,c和d之间的内部联接优先于交叉联接。因此,在评估内部连接条件时,列a.group_id不可用。当您从最终查询中的内连接条件中取出表时,查询不再具有冲突的优先级。

答案 2 :(得分:1)

这里的问题是混合类型。在FROM子句中使用逗号分隔表时,将单独计算每个术语。请看以下示例:

From 
    SCHEMA_A.TABLE_A a,
    SCHEMA_B.TABLE_B b,
    SCHEMA_A.TABLE_D d
Join 
    SCHEMA_C.TABLE_C c
On
    b.friend_id = c.friend_id

数据库正在尝试解析SCHEMA_A.TABLE_D d Join SCHEMA_C.TABLE_C c On b.friend_id = c.friend_id。在此范围内,b没有意义(它是一个单独的术语)。

对于您的第三个版本,我得到"A"."GROUP_ID": invalid identifier,这也符合此解释。

最后,你应该从中学到的教训不是混合连接类型。