ORA-00918:SELECT *中模糊定义的列

时间:2011-06-03 22:00:38

标签: sql oracle ora-00918

获取ORA-00918:列模糊定义:运行此SQL:

SELECT *
FROM
  (SELECT DISTINCT(coaches.id),
    people.*,
    users.*,
    coaches.*
  FROM "COACHES"
  INNER JOIN people ON people.id = coaches.person_id
  INNER JOIN users ON coaches.person_id = users.person_id
  LEFT OUTER JOIN organizations_users ON organizations_users.user_id = users.id
) WHERE rownum <= 25

有什么建议吗?

3 个答案:

答案 0 :(得分:46)

查询的投影只能有一个给定名称的实例。正如您的WHERE子句所示,您有几个表,其中包含一个名为ID的列。由于您选择*,因此您的投影会有多个名为ID的列。或者它不会让编译器投掷ORA-00918。

解决方案非常简单:您必须扩展投影以显式选择命名列。然后你可以省略重复的列,只保留(比如说)COACHES.ID或使用列别名:coaches.id as COACHES_ID

也许这会打击你很多打字,但这是唯一的方法。如果它是舒适的,SELECT *在生产代码中被认为是不好的做法:明确命名的列更安全。

答案 1 :(得分:9)

您的内部查询中有多个名称相同的列,因此在外部查询中引发错误。如果你摆脱外部查询,它应该运行,虽然仍然令人困惑:

SELECT DISTINCT
    coaches.id,
    people.*,
    users.*,
    coaches.*
FROM "COACHES"
    INNER JOIN people ON people.id = coaches.person_id
    INNER JOIN users ON coaches.person_id = users.person_id
    LEFT OUTER JOIN organizations_users ON organizations_users.user_id = users.id
WHERE
    rownum <= 25

更好(为了可读性和性能),准确指定每个表中需要哪些字段,而不是全部选择它们。然后,如果您确实需要从不同表中调用相同内容的两个字段,请使用列别名来区分它们。

答案 2 :(得分:1)

在选择对应列可以为null的并集时,也可以看到此错误。

select * from (select D.dept_no, D.nullable_comment
                  from dept D
       union
               select R.dept_no, NULL
                 from redundant_dept R
)

这显然会使解析器混淆,解决方案是将列别名分配给always null列。

select * from (select D.dept_no, D.comment
                  from dept D
       union
               select R.dept_no, NULL "nullable_comment"
                 from redundant_dept R
)

别名不必与相应的列相同,但结果中的列标题由union成员中的第一个查询驱动,因此它可能是一个很好的做法。