Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用联接时,查询抛出ORA-00904无效标识符_Sql_Oracle - Fatal编程技术网

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

Sql 使用联接时,查询抛出ORA-00904无效标识符,sql,oracle,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.fr

我遇到了一些奇怪的行为,这些行为阻止了我以我喜欢的方式设置查询。如果您有任何想法,我将不胜感激。如果有任何关于表格的信息对我有帮助,请告诉我。我仔细看了看,没有任何东西向我扑来,这可能会导致这种情况,但我也不知道我在寻找什么。这就是行为

这很好:

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\u id=c.friend\u 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
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
这将返回ORA-00904:b.group\U cd=d.group\U cd:无效标识符

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
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

尝试使用
关键字,该关键字是为同一列名上的
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;
另外,请确保使用正确的用户执行其他查询,因为没有正确权限的用户将抛出无效标识符

编辑:实际问题是您正在将
表C
表D
连接,但连接条件引用了
表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
子句中提到的最后一个表,因此它无法访问
表B


对于可能有
无效标识符错误的其他人,请确保您的数据库不区分大小写,否则请确保使用正确的大小写。

我相信您已经遇到了SQL中处理连接作用域/优先级的复杂性。由于我自己不是一名数据库程序员,我无法真正告诉您为什么它会这样工作,但我确实看到了查询解析器行为的一些逻辑

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

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


在第三个查询中,表b、c和d之间的内部联接优先于交叉联接。因此,列
a.group\u id
在计算内部联接条件时不可用。在最终查询中将表a从内部联接条件中取出时,查询不再具有冲突的优先级。

这里的问题是联接类型的混合。当您在
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
数据库正在尝试解析b.friend\u id=C.friend\u id
上的架构A.TABLE\D加入架构C.TABLE\C。在此范围内,
b
没有任何意义(它是一个单独的术语)

对于您的第三个版本,我得到了
“A”。“GROUP\u ID”:无效标识符,这也符合此解释


最后,您应该从中吸取的教训是不要混合联接类型。

他已经有了成功运行的代码。他正在寻找不一致行为的解释。另一种可能是区分大小写,但您的两个查询都是以相同的方式编写的。完全是这样。我没有意识到这样的工作,但它现在有了完美的意义。非常感谢!仅供参考,我认为使用的问题是,它应该更换,而不是跟进it@philfo是的,如果
使用
关键字,则在
上不能有
我的错误,我将进行编辑。这就是为什么您不应该将旧的Oracle类型联接与正确的ANSI类型联接混合使用,因为联接顺序和范围变得更加不清晰。。。坚持其中之一,最好是ANSI*8-)它们不是真正的交叉连接;使用旧的逗号分隔表语法,Oracle使用
where
条件作为联接条件。(事实上,它仍然可以与ANSI连接,但这是另一个故事)。但你仍然是对的,C和D首先连接,B不在范围内。实际上,逗号分隔的表列表是一个隐含的交叉连接。看见这就是为什么出于可读性和性能原因不鼓励这种做法。在同一页中:“交叉连接的结果可以通过使用WHERE子句进行过滤,该子句可能会产生与内部连接等效的结果。”我同意这是一种没有
WHERE
的交叉连接,但是,因为有一个内部连接,所以它是一个内部连接-虽然当您使用ANSI术语来表示Oracle的语法(甚至*8-)时,这个术语会有点尴尬,但我在很大程度上是在吹毛求疵。您是对的,返回的结果将与内部连接相同,但是查询解析器获得该结果的方式可能会大不相同。如果您正在处理一个非常大的数据集,必须加载所有记录,对所有记录应用交叉连接,那么过滤器将在内存中生成一个巨大的数据集。希望查询解析器能够将交叉连接优化为内部连接。如果是这样,那么你说它们是等价的是绝对正确的。除非有这样的保证,否则我不会说与
WHERE
的交叉连接与内部连接相同。@bluecollarcoder:在应用
WHERE
条件之前,它在逻辑上是交叉连接,但数据库不会这样计算。如果您查看OP中查询的解释计划,则不会看到笛卡尔积。很长一段时间以来,数据库一直在评估
where
子句中的联接,并在优化查询时将其考虑在内。