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

クエリのプロジェクションは、指定された名前のインスタンスを1つだけ持つことができます。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

とにかくすべてを選択するのではなく、各テーブルから必要なフィールドを正確に指定する方が(読みやすさとパフォーマンスの両方の点で)はるかに優れています次に、異なるテーブルから同じものと呼ばれる2つのフィールドが本当に必要な場合は、列エイリアスを使用してそれらを区別します。

于 2011-06-03T22:23:30.987 に答える
2

対応する列がnullになる可能性があるユニオンを選択するときにも、このエラーが発生する可能性があります。

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

これは明らかにパーサーを混乱させます。解決策は、常にnull列に列エイリアスを割り当てることです。

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 に答える