带有左外连接子查询的Oracle问题

时间:2015-10-28 17:20:31

标签: sql oracle subquery left-join ora-01427

我有一个sql在左外连接子查询中失败

<textarea class="form-control" cols="25" id="HistoryDetail_2__ReferralComments" name="HistoryDetail[2].ReferralComments" rows="5" style="max-width: 100%; width: 100 %;">
    Comments for the Approval Level
</textarea>
<span class="field-validation-valid" data-valmsg-for="HistoryDetail[2].ReferralComments" data-valmsg-replace="true"></span>

以下是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)

我不知道还有什么可以尝试的。我希望有人这样做!

3 个答案:

答案 0 :(得分:3)

我认为您基本上检查子查询中是否存在该行?如果是,那就做一个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')))

N.B。我更改了aa.location表的别名,只是为了避免外部和子查询的aa.location表之间存在任何可能的冲突(更好地确保别名与现有标识符不同)名称以避免任何潜在的范围冲突问题。此外,它使您在阅读查询时更容易理解。

答案 1 :(得分:1)

您的第一个子查询应该只返回一行,但它返回的不止一行。

这是因为您执行分析函数,本质上应该返回不同数量的行。声明只返回一行的唯一方法是使用聚合函数或使用可确保这一点的条件。

关于第二个查询,请注意您从一个在给定上下文中不存在的表中调用字段。

如果您正在尝试检查是否存在行,则应该读取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中,因为它们只与您需要的一行冲突。

答案 2 :(得分:1)

检查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')))
相关问题