簡體   English   中英

帶有左外部聯接子查詢的Oracle問題

[英]Oracle issue with a left outer join subquery

我有一個SQL,它在左外部聯接子查詢中失敗

ORA-01427: single-row subquery returns more than one row

這是left outer join查詢片段:

 LEFT OUTER JOIN (aa.location) LOCATION
    ON (location_info_300.client_num = location.client_num
    AND location_info_300.source = location.source
    AND location_info_300.location_code = location.location_code
    AND 1 =
           (SELECT ROW_NUMBER()
                   OVER(PARTITION BY location_code, client_num, SOURCE
                        ORDER BY expiry_date DESC)
                      AS rec_order_by_expiry_desc
              FROM aa.location l2
             WHERE location.client_num = l2.client_num
               AND location.source = l2.source
               AND location.location_code = l2.location_code
               AND l2.expiry_date >=
                      TO_DATE('01-JAN-' || location_info_300.reporting_year,
                              'DD-MON-YYYY')
               AND l2.effective_date <=
                      TO_DATE('31-DEC-' || location_info_300.reporting_year,
                              'DD-MON-YYYY')))

我嘗試通過在最后一個AND條件中進行以下更改來修復此問題:

1 = 
(SELECT rec_order_by_expiry_desc
  FROM (SELECT ROW_NUMBER() OVER (PARTITION BY LOCATION_CODE, CLIENT_NUM, SOURCE ORDER BY EXPIRY_DATE DESC) AS REC_ORDER_BY_EXPIRY_DESC
   FROM aa.LOCATION l2
  WHERE location.CLIENT_NUM = l2.CLIENT_NUM
    AND location.SOURCE = l2.SOURCE
    AND location.LOCATION_CODE = l2.LOCATION_CODE
    AND l2.EXPIRY_DATE >= TO_DATE('01-JAN-'||location_info_300.REPORTING_YEAR,'DD-MON-YYYY')
    AND l2.EFFECTIVE_DATE <= TO_DATE('31-DEC-'||location_info_300.REPORTING_YEAR,'DD-MON-YYYY'))
WHERE rec_order_by_expiry_desc = 1)

但是現在我收到以下錯誤:

ORA-00904: "LOCATION_INFO_300"."REPORTING_YEAR": invalid identifier

我不確定還有什么嘗試。 我希望有人這樣做!

我認為您基本上是在檢查子查詢中是否存在該行? 如果是這樣,那么只需執行一個EXISTS

   LEFT OUTER JOIN (aa.location) LOC
                                 ON (location_info_300.client_num = loc.client_num
                                     AND location_info_300.source = loc.source
                                     AND location_info_300.location_code = loc.location_code
                                     AND exists (SELECT null
                                                 FROM   aa.location l2
                                                 WHERE  loc.client_num = l2.client_num
                                                 AND    loc.source = l2.source
                                                 AND    loc.location_code = l2.location_code
                                                 AND    l2.expiry_date >= TO_DATE('01-JAN-' || location_info_300.reporting_year, 'DD-MON-YYYY')
                                                 AND    l2.effective_date <= TO_DATE('31-DEC-' || location_info_300.reporting_year, 'DD-MON-YYYY')))

注意,我更改了aa.location表的別名,只是為了避免外部查詢和子查詢的aa.location表之間可能發生的沖突(最好確保別名與現有的標識符名稱不同,以避免任何潛在的沖突范圍沖突問題。此外,當您閱讀查詢時,它更易於理解)。

您的第一個子查詢應該恰好返回一行,但它返回的行多。

這是因為您執行了分析功能,該功能實際上應該返回可變數量的行。 斷言僅將返回一行的唯一方法是使用聚合函數或使用可確保做到這一點的條件。

關於第二個查詢,請注意,您正在從給定上下文中不存在的表中調用字段。

如果要檢查行是否存在,則應讀入EXISTS函數,或者在子查詢中使用COUNT。

編輯:這是第二個選項的示例(拳頭已張貼):

(SELECT COUNT(*)
              FROM aa.location l2
             WHERE location.client_num = l2.client_num
               AND location.source = l2.source
               AND location.location_code = l2.location_code
               AND l2.expiry_date >= TO_DATE('01-JAN-' || location_info_300.reporting_year, 'DD-MON-YYYY')
               AND l2.effective_date <= TO_DATE('31-DEC-' || location_info_300.reporting_year, 'DD-MON-YYYY'))

請注意,我刪除了PARTITION BY子句中的字段,並且沒有將它們添加到GROUP BY中,因為它們與您僅需要一行的記錄沖突。

檢查1 =(獲取最大有效日期的行號)只是檢查這些條件是否存在最大有效日期,如果是,則將針對客戶,來源和位置的組合返回所有行。 這是你想要的嗎?

如果您想要具有最大失效日期的實際記錄,則

 LEFT OUTER JOIN (aa.location) LOCATION
    ON (location_info_300.client_num = location.client_num
    AND location_info_300.source = location.source
    AND location_info_300.location_code = location.location_code
    AND location.expiry_date =
           (SELECT MAX(expiry_date)
              FROM aa.location l2
             WHERE location.client_num = l2.client_num
               AND location.source = l2.source
               AND location.location_code = l2.location_code
               AND l2.expiry_date >=
                      TO_DATE('01-JAN-' || location_info_300.reporting_year,
                              'DD-MON-YYYY')
               AND l2.effective_date <=
                      TO_DATE('31-DEC-' || location_info_300.reporting_year,
                              'DD-MON-YYYY')))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM