SQL:通过将两列映射到彼此来更新表

10

我有以下两个表:

        Table A
+-------------------+
|___User___|__Value_|
|    3     |  a     |
|    4     |  b     |
|    5     |  c     |
|____6_____|__d_____|



        Table B
+-------------------+
|___User___|__Value_|
|    1     |        |
|    4     |        |
|    5     |        |
|____9_____|________|

我的工作是从表A中获取用户(以及对应的),然后将其映射到表B并插入这些值。因此,在运行脚本后,表B应该如上面的示例所示:

        Table B
+-------------------+
|___User___|__Value_|
|    1     |        |
|    4     |  b     |
|    5     |  c     |
|____9_____|________|

我的问题是,如果Table A包含300,000多个条目,而Table B只有70,000个条目,我该如何构建一个SQL查询以有效地做到这一点?

注:在Table A中,User字段和Value字段都不是唯一的。但是在Table B中,UserValue字段都是唯一的,不应出现多次。两个表格的主键都不是。


3
在与b中的一个用户对应的情况下,如果有2个值,那么应该使用哪个值进行更新? - Mihai
2
如果在表A中有多行相同的“用户”,那么应该将哪一行的“值”复制到B中? - Alan Hadsell
很好的问题@AlanHadsell - 复制哪一行并不重要 - 它可以是Table A中“value”列中任何内容的第一个或最后一个出现。 - Allen S
表A中的每个用户是否都在表B中? - PeterRing
@scaisEdge 不,它们不是。 - Allen S
显示剩余5条评论
3个回答

10

可能是这样

update table_b as b 
inner join table_a as a on a.User = b.User
set b.value = a.value 

1
在现实世界的情况下,更可能需要一个可预测的值,例如对于任何给定的用户,最大的value。在这种情况下,您会希望:
update table_b as b
inner join (
   select user, max(value) from table_a
   group by user ) as a_max on a.user = b.user
set b.value = a_max.value

0
你的问题不清楚关于如何处理已经存在于b中的任何值。如果你使用left join,那么这些值将被显式地设为NULL
update table_b b left join
       table_a a
       on a.User = b.User
    set b.value = a.value;

如果您想保留非匹配项的现有值,则使用inner join

请注意,这可能效率低下,但如果在a(user)上存在索引,则应该可以接受。

如果a中的用户很少,但有很多重复项,则在执行连接之前可能需要聚合a


感谢您提供了详细的回复。有大约50k个用户,是的,有很多重复项(总共300K行)。当前这两个表中都没有索引。我是否能够为这些表添加索引,或者在创建表时就必须完成此操作?此外,“Aggregating Table a”是什么意思? - Allen S
这个表的最佳索引是在 table_a(user, value) 上。 - Gordon Linoff

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接