oracle 如何修复Ora-01427单行子查询在select中返回多行?

krcsximq  于 2023-01-25  发布在  Oracle
关注(0)|答案(4)|浏览(413)

当我执行下面的查询时,我得到如下消息
“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行...

ehxuflar

ehxuflar1#

使用以下查询:

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应该通过检查数据来调查为什么内部查询返回多条记录。这些多条记录真的与业务明智相关吗?

1dkrff03

1dkrff032#

唯一的子查询似乎是这样的-尝试添加一个ROWNUM限制到where以确保:

(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
    ...
6yoyoihd

6yoyoihd3#

(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)
tjvv9vkg

tjvv9vkg4#

我使用这个命令并得到类似[305]的消息:单行查询返回多行:

with catregion as(
select ll.ID, crm.catid, crm.catname,
SUBSTR_REGEXPR('[^_]+' IN "REGIONNAME" OCCURRENCE 3) AS "attr_id", crm.attrname, ll.valint, ll.valreal, ll.valdate, valstr, vallong, VerNum
from CATREGIONMAP crm
join LLAttrData ll on ll.defid = crm.catid and ll.attrid = SUBSTR_REGEXPR('[^_]+' IN "REGIONNAME" OCCURRENCE 3)
WHERE attrname in ('Номер документа SAP','Статус OpenText','Статус документа (SAP)')
),
myselect as(
select DT.DATAID AS cardId,
(select VALSTR from  catregion a where a.catname = 'Атрибуты SAP' and a.attrname = 'Номер документа SAP' AND a.id = DT.DATAID) AS SAP_number,
(select VALSTR from  catregion a where a.catname = 'Договор_основные' and a.attrname = 'Статус OpenText' AND a.id = DT.DATAID) as OpenText_status,
(select VALSTR from  catregion a where a.catname = 'Договор_основные' and a.attrname = 'Статус документа (SAP)' AND a.id = DT.DATAID) as SAP_status
FROM DTREE DT)
SELECT * FROM myselect WHERE SAP_number IN ('SHP000000000000001110002850800000','SHD000000000000001120000682900000','SHP000000000000001110002738900000')

相关问题