2014-01-28 41 views
5

當我執行以下查詢,我得到這樣如何解決Ora-01427單行子查詢在select中返回多行?

消息「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行...

回答

5

使用以下查詢:

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應該調查爲什麼內部查詢通過檢查數據返回多個記錄。這些多個記錄是否真的與商業相關?

+0

好,但一個理由會更好! –

+1

@MaheswaranRavisankar訣竅是強制內部查詢通過添加一個聚合函數來返回唯一的一條記錄(我在這裏使用了'max()')。就查詢而言,這可以很好地工作,但實際上,OP應該調查爲什麼內部查詢通過檢查數據返回多個記錄。這些多個記錄是否真的與商業相關? – hashbrown

+0

我看到聚合MAX()。精細! –

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 
    ... 
+1

'ROWNUM = 1'?這將是錯誤的,因爲內部查詢甚至不會獲取任何記錄 – hashbrown

+1

Rownum是一個僞列。你不能問一個特定的rownum。檢查此:http://www.oracle.com/technetwork/issue-archive/2006/06-sep/o56asktom-086197.html – hashbrown

+0

是的,<=。但是這只是爲了檢查這是導致問題的子查詢。 OP的查詢不像他預期的那樣工作。 – StuartLC

相關問題