【问题标题】:MySQL: How to copy row from one table to another with skipping empty rows in source table?MySQL:如何通过跳过源表中的空行将行从一个表复制到另一个表?
【发布时间】:2020-06-01 20:13:38
【问题描述】:

谁能帮我把这个 PHP/MySQLesque 伪代码变成一个有效的 MySQL 查询?表 A 和 B 具有相同的列/列顺序。

UPDATE B SET 
B.col_1 = A.col_1 IF(A.col_1 != '' AND A.col_1 != 0 AND A.col_1 != NULL), 
B.col_2 = A.col_2 IF(A.col_2 != '' AND A.col_2 != 0 AND A.col_2 != NULL),
…
B.col_n = A.col_n IF(A.col_n != '' AND A.col_n != 0 AND A.col_n != NULL)
WHERE A.$uniqueField = B.$uniqueField

n 列(email、firstName、lastName、phone 等)中的任何一个都可以是 $uniqueField(由 PHP 处理),所以我不能使用 insert-on-duplicate-key。

我发现了很多相反的例子(即复制行并跳过目标表中的空字段),包括通过 COALESCE 的有前途的方法,但我无法让它工作。

任何帮助将不胜感激...在此先感谢!

【问题讨论】:

标签: mysql sql join sql-update


【解决方案1】:

首先,您的更新语句的语法不正确。在 MySQL 中,您需要 UPDATE B JOIN A ON ... SET ... 之类的东西。

说到你要实现的逻辑,虽然很不清楚,但我怀疑这可以用CASE表达式来管理:

UPDATE B 
JOIN A ON A.$uniqueField = B.$uniqueField
SET 
    B.col_1 = CASE 
        WHEN A.col_1 <> '' AND A.col_1 <> '0' 
        THEN A.col_1 
        ELSE B.col_1 
    END,
    B.col_2 = CASE 
        WHEN A.col_2 <> '' AND A.col_2 <> '0'
        THEN A.col_2
        ELSE B.col_2 
    END,
    ...
    B.col_N = CASE 
        WHEN A.col_N <> '' AND A.col_N <> '0'
        THEN A.col_N
        ELSE B.col_N 
    END

对于SET子句中的每一列,查询将其更新为A中的对应值(如果存在这样的记录),如果A中的值不为空,不为null且不为空0。我假设所有列都是字符串数据类型(因此在您的伪代码中是 '0' 而不是 0),因为您确实检查了值是否不是空字符串。

注意:正如 spencer7503 所评论的,空值检查是多余的:满足两个不等式条件中的任何一个的值都保证不为空。

【讨论】:

  • 谢谢!我知道这是不正确的,它根本不是 MySQL,它只是一些伪代码来显示我需要什么。我会试试你的代码,看起来正是我需要的:)
  • +10 请注意,A.col_X IS NOT NULL 的检查是多余的。任何满足&lt;&gt; ''&lt;&gt; '0' 检查的值都将是非NULL。 (与 NULL 值的不等式比较将始终返回 NULL。)我们可以更简洁地编写 WHEN A.col_1 NOT IN ('','0') THEN(对于 col_1 不等于空字符串且不等于字符串 '0' 的非 NULL 值,它将评估为 TRUE
  • @spencer7593:啊,是的,这当然很好。我相应地修改了我的答案。谢谢!
  • 除了关于更简洁的条件检查表达式的注释之外,这是我用来有条件地分配值的模式......诀窍是 ELSE 将列的当前值分配回列本身... +10
  • 复制、研究、理解——就像魅力一样!谢谢大家!让我的查询正常工作并学到了一些新东西——你们让我很开心! :)
【解决方案2】:
UPDATE  B,A

SET B.Col1 = SELECT COALESCE(A.Col1,B.Col1),
    B.Col2  =SELECT COALESCE(A.Col2,B.Col2),
    ...
    B.Coln = SELECT COALESCE(A.Coln.B.Coln)
WHERE A.uniquefield = B.uniquefield  AND Condition

【讨论】:

  • 我们是否有理由选择老式的逗号运算符而不是新的 JOIN 关键字?
  • 这就是我几个小时前尝试的方式。我总是得到(并且得到)一个语法错误,我找不到原因。 :( 谢谢你,我真的很感谢你的帮助!总有一天我会找出语法错误来自哪里...... :)
  • 等效地,您可以使用 UPDATE B INNER JOIN A ON A.uniquefield = B.uniquefield SET B.Col1 = SELECT COALESCE(A.Col1,B.Col1), B.Col2 =SELECT COALESCE( A.Col2,B.Col2), ... B.Coln = SELECT COALESCE(A.Coln.B.Coln) WHERE 条件
  • 如果 A.col 不为空,则查询将 B.col 值更新为 A.col 值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
相关资源
最近更新 更多