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