【问题标题】:mysql how to update a column of every row with a given set of valuesmysql如何使用给定的一组值更新每一行的列
【发布时间】:2015-07-06 02:45:16
【问题描述】:

我想使用给定值集中的值更新表中每一行的列。比如:

id     name     code
---------------------
1      n1       
2      n2     
3      n3 

我有这个值数组 ['code-1','code-2','code3'] 我想设置到每一行,所以对于第一行代码列的值将是'code- 1'来自数组,第二行代码列的值将是'code-2',第三行代码列的值将是来自数组的'code-3'。所以决赛桌会是这样的:

id     name     code
---------------------
1      n1       code-1
2      n2       code-2
3      n3       code-3

如何在一个 sql 查询中做到这一点?

【问题讨论】:

    标签: mysql sql arrays sql-update


    【解决方案1】:

    你可以这样做:

    update table t
        set code = concat('code-', id)
        where id in (1, 2, 3);
    

    如果代码没有真正绑定到 ID,您可以使用 case

    update table t
        set code = (case when id = 1 then 'code-1'
                         when id = 2 then 'code-2'
                         when id = 3 then 'code-3'
                    end)
        where id in (1, 2, 3);
    

    【讨论】:

    • 这很好,但是如果你有超过 100 条记录,你会怎么做呢?
    • 这适用于 100 个值,但我可能会将 id/值对存储在表中并使用 join 进行更新。
    【解决方案2】:

    创建一个新表 (temp) 来保存具有这样架构的数组

    id       code
    -------------
    1       code-1
    2       code-2
    3       code-3
    

    并使用此更新语句更新您的原始表

    UPDATE original
    SET code = temp.code
    FROM original INNER JOIN temp
    ON original.id = temp.id
    

    【讨论】:

    • ic 所以没有专门针对这种情况的sql语句?我必须用不止一个 sql 语句来这样做吗?
    • 如果您计算创建临时表并插入其中所需的语句,那么是的,您不能用一个语句来完成,但实际更新是一次性完成的。
    【解决方案3】:

    您如何识别表格中的“第一行”? “第二行”怎么样?

    要使用 UPDATE 语句,我首先要使用 SELECT 语句,该语句返回行以及要分配的新值。

    您当前拥有的“数组”,如果将其转换为表格将是最简单的。如果您不想定义表并加载它,我们可以使用内联视图,但语句的大小可能会受到限制。

    如果我们运行这个查询,例如:

      SELECT 1 AS rownum, 'code-1' AS code
      UNION ALL SELECT 2, 'code-2'
      UNION ALL SELECT 3, 'code-3'
    

    我们返回结果集中的三行,我们可以像表格一样引用它们。使用额外的 UNION ALL SELECT 扩展它以添加额外的行。

    为了从我们要更新的表中获取对应的rownum值,我们返回主键(或唯一的非空键),并按照我们想要的顺序返回,所以第一行的rownum为1,第二行的 rownum 为 2,以此类推。例如:

      SELECT r.id
           , @rn := @rn + 1 AS rowumn
        FROM mytable r
       CROSS JOIN ( SELECT @rn := 0 ) i
       ORDER BY r.name, r.id
    

    有了这两个结果,我们可以连接回我们要更新的表,返回我们要分配给行的新代码值,例如:

      SELECT t.id
           , t.name
           , t.code AS old_code
           , c.code AS new_code
           , o.rownum
        FROM ( SELECT 1 AS rownum, 'code-1' AS code
               UNION ALL SELECT 2, 'code-2'
               UNION ALL SELECT 3, 'code-3'
             ) c
        JOIN ( SELECT r.id
                    , @rn := @rn + 1 AS rowumn
                FROM mytable r
                CROSS JOIN ( SELECT @rn := 0 ) i
                ORDER BY r.name, r.id
             ) o
          ON o.rownum = c.rownum
        JOIN mytable t
          ON t.id = o.id 
    

    一旦我们对返回我们想要更新的行以及我们想要分配给每一行的新值感到满意,我们可以通过将SELECT ... FROM 替换为UPDATE 将其转换为UPDATE 语句,并且在语句末尾添加SET 子句。 (如果我们有 WHERE 子句,则在 WHERE 子句之前。)

      UPDATE ( SELECT 1 AS rownum, 'code-1' AS code
               UNION ALL SELECT 2, 'code-2'
               UNION ALL SELECT 3, 'code-3'
             ) c
        JOIN ( SELECT r.id
                    , @rn := @rn + 1 AS rowumn
                FROM mytable r
                CROSS JOIN ( SELECT @rn := 0 ) i
                ORDER BY r.name, r.id
             ) o
          ON o.rownum = c.rownum
        JOIN mytable t
          ON t.id = o.id 
         SET t.code = c.code
    

    我就是这样做的。

    如果“新代码”数组中的行数很大,我会创建一个表,并将数组值加载到表中。然后将内联视图查询c 替换为对表的引用。

        FROM my_new_code_table c
    

    或者,我可以将语句分成可管理的块。做 20 个代码,然后为下一组 20 行:

           ( SELECT 21 AS rownum, 'code-21' AS code 
             UNION ALL SELECT 22, 'code-22'
             ... 
             UNION ALL SELECT 40, 'code-40'
           ) c
    

    【讨论】:

      【解决方案4】:

      我想出了一个不同的解决方案来解决我的问题,因为我有数千个条目需要使用连接来更正:

      UPDATE `entry`
      JOIN 
      ( *DEFINE QUERY FOR LOOKUPTABLE HERE* ) as alias
      on alias.id=entry.valuetoreplace
      SET `valuetoreplace` = alias.newvalue;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-18
        相关资源
        最近更新 更多