【问题标题】:How to fix Ora-01427 single-row subquery returns more than one row in select?如何修复 Ora-01427 单行子查询在选择中返回多行?
【发布时间】:2014-01-28 05:37:56
【问题描述】:

当我执行以下查询时,我收到类似

的消息

“Ora-01427 单行子查询返回多行”

SELECT E.I_EmpID AS EMPID,
       E.I_EMPCODE AS EMPCODE,
       E.I_EmpName AS EMPNAME,
       REPLACE(TO_CHAR(A.I_REQDATE, 'DD-Mon-YYYY'), ' ', '') AS FROMDATE,
       REPLACE(TO_CHAR(A.I_ENDDATE, 'DD-Mon-YYYY'), ' ', '') AS TODATE,
       TO_CHAR(NOD) AS NOD,
       DECODE(A.I_DURATION,
              'FD',
              'FullDay',
              'FN',
              'ForeNoon',
              'AN',
              'AfterNoon') AS DURATION,
       L.I_LeaveType AS LEAVETYPE,
       REPLACE(TO_CHAR((SELECT C.I_WORKDATE
                         FROM T_COMPENSATION C
                        WHERE C.I_COMPENSATEDDATE = A.I_REQDATE
                          AND C.I_EMPID = A.I_EMPID),
                       'DD-Mon-YYYY'),
               ' ',
               '') AS WORKDATE,
       A.I_REASON AS REASON,
       AP.I_REJECTREASON AS REJECTREASON
  FROM T_LEAVEAPPLY A
 INNER JOIN T_EMPLOYEE_MS E
    ON A.I_EMPID = E.I_EmpID
   AND UPPER(E.I_IsActive) = 'YES'
   AND A.I_STATUS = '1'
 INNER JOIN T_LeaveType_MS L
    ON A.I_LEAVETYPEID = L.I_LEAVETYPEID
  LEFT OUTER JOIN T_APPROVAL AP
    ON A.I_REQDATE = AP.I_REQDATE
   AND A.I_EMPID = AP.I_EMPID
   AND AP.I_APPROVALSTATUS = '1'
 WHERE E.I_EMPID <> '22'
 ORDER BY A.I_REQDATE DESC

当我在没有 ORDER BY A.I_REQDATE DESC 的情况下执行此操作时,它返回 100 行...

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    使用以下查询:

    SELECT E.I_EmpID AS EMPID,
           E.I_EMPCODE AS EMPCODE,
           E.I_EmpName AS EMPNAME,
           REPLACE(TO_CHAR(A.I_REQDATE, 'DD-Mon-YYYY'), ' ', '') AS FROMDATE,
           REPLACE(TO_CHAR(A.I_ENDDATE, 'DD-Mon-YYYY'), ' ', '') AS TODATE,
           TO_CHAR(NOD) AS NOD,
           DECODE(A.I_DURATION,
                  'FD',
                  'FullDay',
                  'FN',
                  'ForeNoon',
                  'AN',
                  'AfterNoon') AS DURATION,
           L.I_LeaveType AS LEAVETYPE,
           REPLACE(TO_CHAR((SELECT max(C.I_WORKDATE)
                             FROM T_COMPENSATION C
                            WHERE C.I_COMPENSATEDDATE = A.I_REQDATE
                              AND C.I_EMPID = A.I_EMPID),
                           'DD-Mon-YYYY'),
                   ' ',
                   '') AS WORKDATE,
           A.I_REASON AS REASON,
           AP.I_REJECTREASON AS REJECTREASON
      FROM T_LEAVEAPPLY A
     INNER JOIN T_EMPLOYEE_MS E
        ON A.I_EMPID = E.I_EmpID
       AND UPPER(E.I_IsActive) = 'YES'
       AND A.I_STATUS = '1'
     INNER JOIN T_LeaveType_MS L
        ON A.I_LEAVETYPEID = L.I_LEAVETYPEID
      LEFT OUTER JOIN T_APPROVAL AP
        ON A.I_REQDATE = AP.I_REQDATE
       AND A.I_EMPID = AP.I_EMPID
       AND AP.I_APPROVALSTATUS = '1'
     WHERE E.I_EMPID <> '22'
     ORDER BY A.I_REQDATE DESC
    

    诀窍是通过添加一个聚合函数来强制内部查询只返回一条记录(我在这里使用了 max() )。就查询而言,这将完美地工作,但老实说,OP 应该通过检查数据来调查内部查询返回多条记录的原因。这些多条记录真的与业务相关吗?

    【讨论】:

      【解决方案2】:

      唯一的子查询似乎是这个 - 尝试将 ROWNUM 限制添加到确定位置:

      (SELECT C.I_WORKDATE
               FROM T_COMPENSATION C
               WHERE C.I_COMPENSATEDDATE = A.I_REQDATE AND ROWNUM <= 1
               AND C.I_EMPID = A.I_EMPID)
      

      但是,您确实需要调查为什么这不是唯一的 - 例如该员工在匹配日期可能拥有多个C.I_COMPENSATEDDATE

      出于性能原因,您还应该查看查找子查询是否可以重新排列为内/左连接,即

       SELECT 
          ...
          REPLACE(TO_CHAR(C.I_WORKDATE, 'DD-Mon-YYYY'),
                  ' ',
                  '') AS WORKDATE,
          ...
       INNER JOIN T_EMPLOYEE_MS E
          ...
           LEFT OUTER JOIN T_COMPENSATION C
                ON C.I_COMPENSATEDDATE = A.I_REQDATE
                AND C.I_EMPID = A.I_EMPID
          ...
      

      【讨论】:

      【解决方案3】:
      (SELECT C.I_WORKDATE
               FROM T_COMPENSATION C
               WHERE C.I_COMPENSATEDDATE = A.I_REQDATE AND ROWNUM <= 1
               AND C.I_EMPID = A.I_EMPID)
      

      【讨论】:

        猜你喜欢
        • 2015-07-04
        • 1970-01-01
        • 1970-01-01
        • 2022-01-08
        • 2017-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-06-24
        相关资源
        最近更新 更多