【问题标题】:MySQL Update with IF-Condition treats 0 like '' or NULLMySQL Update with IF-Condition 将 0 视为 '' 或 NULL
【发布时间】:2015-12-08 12:32:51
【问题描述】:

给定 2 个表 tbl1 和 tbl2。如果 tbl2 中的值不是 NULL 或空字符串 (''),则 tbl1 中的值应在相应行中更新/替换为 tbl2 中的值。出于任何原因,MySQL(和 MariaDB)将 0 值视为空字符串或 NULL 值。有什么办法可以解决吗?

编辑:这只是一个简单的例子。实际上,我不知道该字段的类型。这是一个自动化的 PHP 脚本,它为两个表中存在的每个字段生成查询的 SET 语句。这可以是字符串或(微小)整数字段、文本等。我​​猜脚本应该检查字段的类型并根据字段的类型决定如何构建语句的 IF 部分。当我正确理解 cmets 时,我不能指望在整数字段上进行类似字符串的比较的有用结果。 //

http://sqlfiddle.com/#!9/573fc

UPDATE
  tbl1 t1,
  tbl2 t2 
SET 
  t1.val = IF(t2.val != '' AND t2.val IS NOT NULL, t2.val, t1.val)
WHERE
  t1.id = t2.id;

让我们假设 tbl1:

id | val
1  | 1

让我们假设 tbl2:

id | val
1  | 0

现在我想用 tbl2 的 val 的值更新 tbl1 中的 val,如果 tbl2 中的 val 既不是 NULL 也不是空字符串。由于 tbl2 中的 val 为 0,因此 tbl1 中的 val 也应为 0。但这不会发生。我不知道为什么。如果 tbl2 中的 val 为 1、2、3 或其他任何不同于 0、NULL 或 '' 的值,则上面的查询可以正常工作。

真正的查询更复杂,并且更新更多字段,具体取决于它们的值。但这部分是困扰我的部分。而且由于字段可以有不同的类型(字符串、整数、日期等),我无法真正“解决它”。

编辑 2/解决方案/解决方法:

由于我无法对代码和数据库进行太多更改,因此我想出了这个解决方案。它可能不是最漂亮的,也远非整洁干净,但它确实有效。

UPDATE
  tbl1 t1,
  tbl2 t2 
SET 
  t1.val = IF((t2.val != '' AND t2.val IS NOT NULL) OR t2.val = '0', t2.val, t1.val)
WHERE
  t1.id = t2.id;

【问题讨论】:

    标签: mysql


    【解决方案1】:

    问题出在这个谓词上:

    t2.val != ''
    

    t2.val = 0 时,这将评估为true。这是由于隐式类型覆盖。请查看this demo 亲自查看。

    谓词不是必需的,因为valtinyint(3) 类型(根据提供的sql fiddle 中给出的表定义)。所以把它从你的UPDATE 声明中去掉,你就可以开始了。

    【讨论】:

      【解决方案2】:

      您可以更简单地编写查询:

      UPDATE tbl1 t1 JOIN
             tbl2 t2 
             ON t1.id = t2.id
          SET t1.val = t2.val
          WHERE t2.val IS NOT NULL;
      

      Giorgos 解释说,您的查询的主要问题是数值列与字符串的比较——以及由此产生的隐式类型转换。

      不过,这个版本也有:

      • 修复了使用显式JOIN 语法的逻辑,因此查询的意图更加清晰。
      • 将比较逻辑移至WHERE 子句。这使查询更加高效,因为它不会尝试更新所有行。

      【讨论】:

      • 好吧,这只是指出主要问题的一个简短示例。事实上,这是一个复杂得多的查询,涉及多个表和超过 20000 个字段,如果它们在右侧有值,则在左侧进行比较和更新。但我明白你的主要观点。
      【解决方案3】:

      如果 tbl2 中的列 val 是一个整数字段,所以你不能把 '' int 它,它会返回 0。所以你只能检查空值。在这种情况下,您的查询将正常工作。

       UPDATE
        tbl1 t1,
        tbl2 t2 
      SET 
        t1.val = IF( t2.val IS NOT NULL, t2.val, t1.val)
      WHERE
        t1.id = t2.id;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多