【问题标题】:UPDATE SET values from list更新列表中的 SET 值
【发布时间】:2017-10-18 00:58:13
【问题描述】:

我在使用列表中的新值更新表时遇到问题。

我的数据如下所示:

id  value_1  value_2

1   11       21

2   32       41

3   43       84

... 

我已经用 INSERT 命令在表中写入了列 id 和 value_1。在这一步,我无法写入 value_2 列,因为我还需要计算它,所以我想稍后用 value_2 列的值数组更新表。

我想要这样的代码:

UPDATE table_name SET value_2 = (21,41,84) WHERE id IN (1,2,3)

不幸的是,不可能像这样从列表中设置 value_2,它仅适用于单个值。

我得到了一个解决方法,即在整个 UPDATE 查询上编写一个 for 循环,但这对我的程序来说太慢了。 任何人都可以建议我如何使其正常工作?

整个查询都是用 Python 执行的。

【问题讨论】:

  • 你需要做 3 x UPDATE
  • 这就是UPDATE 语句的工作方式。它可以修改多行,但会将所有行的字段value_2 设置为相同的新值。您描述的功能在 SQL 中不存在。您必须发出 3 个不同的 UPDATE 查询才能将三行的字段 value_2 更改为三个不同的值。
  • @InnovaITveSolutions 请注意,您不需要在标题中添加标签信息。
  • 我认为你可以查询一个数据列表并使用 group_concat() 创建一个动态查询,然后执行它们。

标签: mysql sql mysql-python


【解决方案1】:

在尝试了不同的事情之后,我可以找到一个解决方案,使用值列表作为输入快速更新表的值。

我定位于这个问题 (https://stackoverflow.com/a/3466/7997169) 中提出的想法,并对其进行了修改以处理列表。

作为输入,我有这样的列表:

id = [1, 2, 3, ... ]
value_1 = [11, 32, 41, ... ]
value_2 = [21, 41, 84, ... ]

使用 Python MySQL 连接器,我可以将整个更新循环写入一个查询命令。因此,我将列表中的数据写入了如下所示的字符串:

VALUES (1,11,21),(2,32,41),(3,41,84),....

总代码如下:

for i in range(0,len(id),1):
    a = '(' + str(id[i]) + ',' + str(value_1[i]) + ',' + str(value_2[i]) + ')'
    b = ','
    if i < (len(id)-1):
        c = c + a + b
    else:
        c += a

update_cell_info = ("INSERT INTO table (id, value_1, value_2)"
                      "VALUES %s" % c +
                      "ON DUPLICATE KEY UPDATE "
                      "value_1=VALUES(value_1),"
                      "value_2=VALUES(value_2)"
                      ";")
cursor.execute(update_cell_info)

最后,这个过程比我使用 for 循环用新变量迭代更新过程的前一个过程快 10 倍以上。

【讨论】:

    【解决方案2】:

    这可以通过一个UPDATE 来完成,使用case 表达式来设置想要的值。像这样的:

    UPDATE table_name
    SET value_2 = case id when 1 then 21
                          when 2 then 41
                          when 3 then 84
                  end
    WHERE id IN (1,2,3)
    

    但是,我不知道这是否会产生任何性能差异。

    【讨论】:

    • 谢谢,这个答案至少对小数据量很有用,但是我的数据每列大约有 10000 个值,所以我不能为每个值做一个案例。是否可以在case表达式中实现列表?
    • @Philipp 像所有人一样在事务中进行多次更新。您可以制作临时表,在那里插入新数据,然后进行一次更新,但这是个坏主意
    • 但是BEGIN...COMMIT 大约有 10K 更新;这会加快一些速度。
    • 如果我们在 CASE 中硬编码值,那么为什么我们需要这样做,我们可以使用那些更新查询。
    猜你喜欢
    • 2018-04-28
    • 1970-01-01
    • 2020-01-03
    • 2017-11-23
    • 1970-01-01
    • 2022-11-20
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    相关资源
    最近更新 更多