[英]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.