使用临时表中的值更新表中的多个行

时间:2014-03-05 10:20:50

标签: mysql

我正在尝试编写数据库迁移脚本,以便将列添加到包含现有数据的表中,然后使用适当的数据填充该列。

我正在通过几个步骤进行迁移。我创建了一个临时表,其中包含一个带有这样的ID的列:

new_column
==========
1000
1001
1002
1003
...  

我现在想要更新现有表,以便上面临时表中的每一行用于更新现有表中的每一行。现有表格如下所示:

old_column_1 | old_column_2 | new_column
========================================
1            | 100          | null
2            | 101          | null
3            | 102          | null
...

我尝试过这种更新的一些变体 -

select min(t.new_column) 
from temp t 
where t.new_column not in (select new_column from existing_table);

但我似乎无法正确理解语法......

1 个答案:

答案 0 :(得分:0)

你的问题比你想象的要复杂得多。加入是没有可靠的。那么,要么你编写一个存储过程,它使用游标循环遍历两个表并逐行更新现有的表(这可能很快成为性能噩梦,因此我不推荐它)或者你使用这个有点复杂的查询:

CREATE TABLE temp
    (id int auto_increment primary key, `new_column` int)
;

INSERT INTO temp
    (`new_column`)
VALUES
    (1000),
    (1001),
    (1002),
    (1003)
;



CREATE TABLE existing
    (`old_column_1` int, `old_column_2` int, `new_column` varchar(4))
;

INSERT INTO existing
    (`old_column_1`, `old_column_2`, `new_column`)
VALUES
    (1, 100, NULL),
    (2, 101, NULL),
    (3, 102, NULL)
;

update 
existing e 
inner join (
  select * from (
    select
    t.*
    from temp t
  )t
  inner join
  (
    select
    e.old_column_1, e.old_column_2,
    @rownum := @rownum + 1 as rn
    from existing e
    , (select @rownum:=0) vars
  )e on t.id = e.rn
) sq on sq.old_column_1 = e.old_column_1 and sq.old_column_2 = e.old_column_2
set e.new_column = sq.new_column;

我在临时表中添加了一个auto_increment列。要么你这样做,要么像我在这里模拟一个rownumber:

    select
    e.old_column_1, e.old_column_2,
    @rownum := @rownum + 1 as rn
    from existing e
    , (select @rownum:=0) vars

如果您想影响哪一行获得哪个行号,可以在那里使用ORDER BY whatever_column ASC|DESC

因此,查询的基本功能是,在现有表中创建行号,并通过此列和临时表中的auto_increment列连接它。然后我再次将此子查询连接到现有表,以便我们可以轻松地将列从临时表复制到现有表。