38

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

请问有什么建议吗?

4

4 回答 4

60

一个查询的投影只能有一个给定名称的实例。正如您的 WHERE 子句所示,您有几个表,其中包含一个名为 ID 的列。因为您正在选择*您的投影,所以将有几列称为 ID。或者,如果不是编译器抛出 ORA-00918,它就会出现。

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

也许这会让你觉得打字很多,但这是唯一的方法。如果有任何安慰,SELECT *在生产代码中被认为是不好的做法:显式命名的列更安全。

于 2011-06-03T22:24:37.037 回答
11

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

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

从每个表中准确指定您需要的字段而不是全部选择它们会更好(对于可读性和性能两者)。然后,如果您确实需要两个来自不同表的称为同一事物的字段,请使用列别名来区分它们。

于 2011-06-03T22:23:30.987 回答
2

在选择对应列可以为空的联合时,您也可以看到此错误。

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

这显然使解析器感到困惑,解决方案是将列别名分配给始终为空的列。

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

别名不必与对应的列相同,但结果中的列标题由联合成员中的第一个查询驱动,因此这可能是一个好习惯。

于 2017-08-03T19:09:07.580 回答
-1
SELECT  DISTINCT  
        per_all_people_f.EMPLOYEE_NUMBER 
        , MAX(per_all_people_f.LAST_UPDATE_DATE) 
        , per_all_people_f.KNOWN_AS  FULL_NAME
        , to_char(notified_termination_date, 'DD-MM-YYYY') AS termination_date 
        , :FROM_DATE  DATE1
        , :TO_DATE DATE2
--      , D_LEAVING_REASON AS D_LEAVING_REASON
        , CASE substr(substr(hr_all_organization_units_tl.NAME, instr(hr_all_organization_units_tl.NAME, '.') + 1), 1, 1)
        WHEN 'B'  THEN
            'إدارة الاتصالات وتقنية المعلومات'
        WHEN 'C'  THEN
            'إدارة المشاريع'
        WHEN 'D'  THEN
            'الإدارة القانونية'
        WHEN 'E'  THEN
            'إدارة الصحه والسلامة والبيئه'
        WHEN 'F'  THEN
            'إدارة هندسة المكامن والانتاج'
        WHEN 'G'  THEN
            'إدارة الهندسة'
        WHEN 'H'  THEN
            'إدارة العمليات'
        WHEN 'J'  THEN
            'إدارة الحفر وصيانة الآبار'
        WHEN 'K'  THEN
            'إدارة المواد'
        WHEN 'L'  THEN
            'إدارة النقل والخدمات'
        WHEN 'M'  THEN
            'إدارة الاستكشاف'
        WHEN 'N'  THEN
            'إدارة فرع بنغازي'
        WHEN 'P'  THEN
            'إدارة التخطيط'
        WHEN 'R'  THEN
            'إدارة المالية'
        WHEN 'T'  THEN
            'إدارة المراجعه'
        WHEN 'W'  THEN
            'إدارة التدريب والتطوير'
        WHEN 'Y'  THEN
            'إدارة شؤون الموظفين'
            else case  substr(substr(hr_all_organization_units_tl.NAME, instr(hr_all_organization_units_tl.NAME, '.') + 1), 1, 3)
              WHEN 'A11'  THEN
            'لجنة المناقصات'
        WHEN 'A10'  THEN
            'لجنة الادارة'
        WHEN 'A12'  THEN
            'قسم الاعلام '
            end
        END  DEPARTMENT
    , CASE d_leaving_reason 
        WHEN 'Retirement'  THEN
            'التقاعد'
        END 
        LEAVING_REASON1 
FROM    per_all_people_f
LEFT JOIN per_periods_of_service_v ON per_all_people_f.person_id = per_periods_of_service_v.person_id
LEFT JOIN per_assignments_f ON per_all_people_f.EMPLOYEE_NUMBER = per_assignments_f.ASSIGNMENT_NUMBER
LEFT JOIN hr_all_organization_units_tl ON per_assignments_f.ORGANIZATION_ID = hr_all_organization_units_tl.ORGANIZATION_ID
WHERE   notified_termination_date >= TO_DATE(:FROM_DATE,'MM-YYYY') AND notified_termination_date <= TO_DATE(:TO_DATE,'MM-YYYY')
--      AND D_LEAVING_REASON = 'Retirement'
        AND CURRENT_EMPLOYEE_FLAG IS NULL AND employee_number IS NOT NULL
GROUP BY EMPLOYEE_NUMBER,d_leaving_reason,LAST_UPDATE_DATE,KNOWN_AS,notified_termination_date
,:FROM_DATE,:TO_DATE,NAME
于 2021-11-06T21:39:09.987 回答