基于另一个表的映射更新表的值的最有效方法是什么

时间:2018-05-23 09:46:12

标签: oracle plsql sql-update

我有一张包括以下细节的表格。

empID   department  location    segment 
1   23  55  12
2   23  11  12
3   25  11  39

我还有一个映射表,如下面的

Field   old value   new value
Department  23  74
department  25  75
segment   10    24
location    11  22  

所以我的任务是用新值替换旧值。我实际上可以使用游标并首先更新部门然后分段等等。但这是耗时且低效的。我想知道是否有任何有效的方法来做到这一点。如果我们计划在映射中添加更多列,那么将来还需要支持。

欢呼声。

2 个答案:

答案 0 :(得分:2)

检查是否可以解决问题。

update emp set department = (select map.new_value from map where emp.department = map.old_value);

答案 1 :(得分:1)

如何将数据复制到新表?

CREATE TABLE newemp AS
SELECT e.empid,
       NVL(d.new_value, e.department) AS department,
       NVL(l.new_value, e.location)   AS location,
       NVL(s.new_value, e.segment)    AS segment
  FROM emp e
  LEFT JOIN map d ON d.field='DEPARTMENT' AND e.department = d.old_value
  LEFT JOIN map l ON l.field='LOCATION'   AND e.location   = d.old_value
  LEFT JOIN map s ON s.field='SEGMENT'    AND e.segment    = d.old_value
 ORDER BY e.empid;

EMPID   DEPARTMENT  LOCATION    SEGMENT
1   84  55  12 
2   84  11  12
3   75  11  39

您显然需要通过映射表三次,但只有一次通过emp表。

我们使用LEFT JOIN,因为并非所有值都会被更改。如果未找到new_value,则NVL函数使用emp表的现有值。

您可以从此新表更新原始表(如果新表具有主键):

UPDATE (SELECT empid,
               e.department as old_department, 
               n.department as new_department, 
               e.location   as old_location,
               n.location   as new_location,
               e.segment    as old_segment,
               n.segment    as new_segment
          FROM emp  e
          JOIN newemp n USING (empid))
  SET old_department = new_department,
      old_location   = new_location,
      old_segment    = new_segment
WHERE old_department != new_department
   OR old_location   != new_location
   OR old_segment    != new_segment;