【问题标题】:Updating row of one table using rows of another table based on specific conditions根据特定条件使用另一个表的行更新一个表的行
【发布时间】:2015-10-07 06:51:06
【问题描述】:

我想根据以下条件使用EMPLOYEE_MST 表中的OFFICE_ID,OFFICE_TYPE 更新FA_SUBLEDGER_MST 表的OFFICE_ID,OFFICE_TYPE

EMPLOYEE_MST.SL_CODE=FA_SUBLEDGER_MST.SL_CODE EMPLOYEE_MST.OFFICE_ID<>SL.OFFICE_ID OR EMPLOYEE_MST.OFFICE_TYPE<>SL.OFFICE_TYPE AND EMPLOYEE_MST.OFFICE_TYPE!='DHB'.

我试过这个查询:

UPDATE FA_SUBLEDGER_MST sl
SET
  (
    sl.OFFICE_ID,sl.OFFICE_TYPE
  )
  =
  (SELECT emp.OFFICE_ID,
  emp.OFFICE_TYPE
  FROM EMPLOYEE_MST emp
  WHERE emp.OFFICE_ID<>sl.OFFICE_ID
  OR emp.OFFICE_TYPE<>sl.OFFICE_TYPE
  AND sl.SL_CODE      = emp.SL_CODE
  AND emp.OFFICE_TYPE!='DHB'
  )
WHERE sl.STATUS = 'A'
AND EXISTS
  (SELECT 1
  FROM EMPLOYEE_MST emp
  WHERE emp.OFFICE_ID<>sl.OFFICE_ID
  OR emp.OFFICE_TYPE<>sl.OFFICE_TYPE
  AND emp.SL_CODE=sl.SL_CODE  
  AND emp.OFFICE_TYPE!='DHB'
  );

还有这个:

UPDATE FA_SUBLEDGER_MST
SET
  (
    OFFICE_ID,
    OFFICE_TYPE
  )
  =
  (SELECT OFFICE_ID,
    OFFICE_TYPE
  FROM EMPLOYEE_MST
  WHERE FA_SUBLEDGER_MST.OFFICE_ID != EMPLOYEE_MST.OFFICE_ID
  OR FA_SUBLEDGER_MST.OFFICE_TYPE!  =EMPLOYEE_MST.OFFICE_TYPE
  AND FA_SUBLEDGER_MST.SL_CODE      = EMPLOYEE_MST.SL_CODE
  AND EMPLOYEE_MST.OFFICE_TYPE!     ='DHB'
  ) ;

但是两者都导致了这个错误:

SQL 错误:ORA-01427:单行子查询返回多行
01427. 00000 - “单行子查询返回多于一行

我也试过了:

UPDATE
  (SELECT em.OFFICE_ID emoffid,
    SL.OFFICE_ID sloffid,
    em.OFFICE_TYPE emofftype,
    SL.OFFICE_TYPE slemofftype,
    SL.STATUS
  FROM EMPLOYEE_MST em
  JOIN FA_SUBLEDGER_MST SL
  ON em.SL_CODE      =SL.SL_CODE
  WHERE em.OFFICE_ID<>SL.OFFICE_ID
  OR em.OFFICE_TYPE <>SL.OFFICE_TYPE
  AND em.OFFICE_TYPE!='DHB'
  AND SL.STATUS      ='A'
  ) t
SET t.sloffid   =t.emoffid
WHERE t.emoffid<>t.sloffid
OR t.emofftype <>t.slemofftype
AND t.emofftype!='DHB'
AND t.STATUS    ='A';

这导致了一个错误:

SQL 错误:ORA-01779:无法修改映射到非键保留表的列
01779. 00000 - “无法修改映射到非键保留表的列”
*原因:试图插入或更新映射到非键保留表的连接视图的列。
*Action:直接修改底层基表。

两个表都包含超过 100,000 条记录,OFFICE_ID 可以是1,2,3,4,5OFFICE_TYPE 可以是'DE','DI','HO',因此它们经常重复。

我需要一个 Oracle 查询来执行此操作。无法使用过程。

非常感谢您的帮助。

【问题讨论】:

  • 第二个最接近,但必须在子查询中引用主FA_SUBLEDGER_MST,才能只返回一行。
  • 嘿,谢谢我在您的评论和UPDATE FA_SUBLEDGER_MST SET ( OFFICE_ID, OFFICE_TYPE ) = (SELECT OFFICE_ID,OFFICE_TYPE FROM EMPLOYEE_MST WHERE (FA_SUBLEDGER_MST.OFFICE_ID != EMPLOYEE_MST.OFFICE_ID OR FA_SUBLEDGER_MST.OFFICE_TYPE! =EMPLOYEE_MST.OFFICE_TYPE) AND FA_SUBLEDGER_MST.SL_CODE = EMPLOYEE_MST.SL_CODE AND EMPLOYEE_MST.OFFICE_TYPE! ='DHB' ) ; 工作后再次查看。 (只是在 OR 条件周围添加了一个 ()。)
  • 但问题是它会更新所有记录。
  • 也许您也需要添加 WHERE 子句?
  • 我尝试使用 where 子句,但无法在其中使用 EMPLOYEE_MST。我改为尝试:WHERE (OFFICE_ID != (select OFFICE_ID from EMPLOYEE_MST where SL_CODE=FA_SUBLEDGER_MST.SL_CODE) and OFFICE_TYPE != (select OFFICE_TYPE from EMPLOYEE_MST where SL_CODE=FA_SUBLEDGER_MST.SL_CODE)) AND SL_CODE = (select SL_CODE from EMPLOYEE_MST where SL_CODE=FA_SUBLEDGER_MST.SL_CODE) AND (select OFFICE_TYPE from EMPLOYEE_MST where SL_CODE=FA_SUBLEDGER_MST.SL_CODE)! ='DHB' ; 但它给出了错误“单行子查询返回多于一行”。 :(

标签: sql database oracle oracle11g


【解决方案1】:

试试这个:

 WHERE (FA_SUBLEDGER_MST.OFFICE_ID != EMPLOYEE_MST.OFFICE_ID AND
        FA_SUBLEDGER_MST.OFFICE_TYPE !=EMPLOYEE_MST.OFFICE_TYPE) --AND will be converted to OR by SQL Engine
  AND FA_SUBLEDGER_MST.SL_CODE      = EMPLOYEE_MST.SL_CODE
  AND EMPLOYEE_MST.OFFICE_TYPE!     ='DHB'
  AND sl.STATUS = 'A' 

【讨论】:

  • 谢谢它解决了一些记录没有被更新的问题。但它更新了所有 124,451 行,它应该更新所有行吗?满足上述指定条件的行只有 4,522 行。
  • 它实际上将所有其他不满足给定条件的行设置为 null。
  • 您的意思是其他行 (124,451 - 4,522) 更新为 Null?
  • yes.. 所有 (124,451 - 4,522) 行的值已更改为 NULL。
【解决方案2】:

试试

UPDATE FA_SUBLEDGER_MST
SET sl.OFFICE_ID = em.OFFICE_ID
,sl.OFFICE_TYPE = em.OFFICE_TYPE
FROM FA_SUBLEDGER_MST sl
INNER JOIN EMPLOYEE_MST em ON em.SL_CODE      =SL.SL_CODE
  WHERE em.OFFICE_ID<>SL.OFFICE_ID
  OR em.OFFICE_TYPE <>SL.OFFICE_TYPE
  AND em.OFFICE_TYPE!='DHB'
  AND SL.STATUS      ='A'

【讨论】:

  • 哦,抱歉,我没有看到 Oracle 标签,这是用于 SQL Server 的。
【解决方案3】:

试试这个代码:

UPDATE FA_SUBLEDGER_MST
SET
  (
    OFFICE_ID,
    OFFICE_TYPE
  )
  =
  (SELECT OFFICE_ID,
    OFFICE_TYPE
  FROM EMPLOYEE_MST
 WHERE ....... 
  ) 
  WHERE (FA_SUBLEDGER_MST.OFFICE_ID != EMPLOYEE_MST.OFFICE_ID AND
        FA_SUBLEDGER_MST.OFFICE_TYPE !=EMPLOYEE_MST.OFFICE_TYPE) 
  AND FA_SUBLEDGER_MST.SL_CODE      = EMPLOYEE_MST.SL_CODE
  AND EMPLOYEE_MST.OFFICE_TYPE!     ='DHB'
  AND sl.STATUS = 'A' ;

【讨论】:

  • 问题是在Update查询EMPLOYEE_MST.下的where子句中不能被SQL识别。它给出的错误为:SQL Error: ORA-00904: "EMPLOYEE_MST"."OFFICE_TYPE": invalid identifier 00904. 00000 - "%s: invalid identifier"
  • 如果你使用Oracle,你应该使用小写的标识符(表/列)
【解决方案4】:

终于找到了解决办法:

 merge into FA_SUBLEDGER_MST s1
    using (
        select SL_CODE, OFFICE_ID, OFFICE_TYPE
        from EMPLOYEE_MST
        where OFFICE_TYPE != 'DHB'
    ) emp
    on (s1.SL_CODE = emp.SL_CODE)
    when matched then update set 
        s1.OFFICE_ID = emp.OFFICE_ID,
        s1.OFFICE_TYPE = emp.OFFICE_TYPE
    where sl.STATUS = 'A'
        and (s1.OFFICE_ID <> emp.OFFICE_ID
        or  s1.OFFICE_TYPE <> emp.OFFICE_TYPE)

;

原帖:Updating row of one table using rows of another table based on specific conditions on https://dba.stackexchange.com/

【讨论】:

    猜你喜欢
    • 2018-08-02
    • 1970-01-01
    • 2022-11-10
    • 2022-01-10
    • 2018-10-08
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多