【问题标题】:Ways to update one table using another skipping null values使用另一个跳过空值更新一个表的方法
【发布时间】:2019-08-03 06:40:02
【问题描述】:

我有table1和table2(都有相同的列),如果table1中不存在table2中的所有记录,我想将它们插入table1,否则我想用table2的所有非NULL列更新table1的列。

我没有设法找到一种方法来生成一个可以同时做这两件事的 sql。 至于第一部分,我使用 INSERT OR IGNORE 进行管理。 第二部分是问题。

这就是我所拥有的:

UPDATE main.datas           
SET ot=(
  SELECT ot FROM cards.datas 
  WHERE main.datas.id = cards.datas.id AND cards.datas.ot <> NULL
); 

问题是,由于cards.datas.ot NULL 部分,整个(SELECT ...)返回NULL。我尝试做cards.datas.ot IS NOT NULL,但它只是忽略它并设置NULL值。

【问题讨论】:

  • 当您想与 NULL 进行比较时,不要使用 = 或 。使用column IS NULLcolumn IS NOT NULL
  • 正如我所说,我已经这样做了。
  • 你确定同一个id的cards.datas.ot不为空吗?
  • 是的,我通过在 main.datas.ot 记录之一中设置一个数字来检查多次,同时在cards.datas.ot 上将相同的 id 设置为 NULL。它将 main 中的数字替换为卡片中的 NULL。

标签: sql sqlite


【解决方案1】:

将 WHERE ... IS NOT NULL 条件放在 UPDATE 语句中:

UPDATE main.datas           
SET ot = (SELECT ot FROM cards.datas WHERE main.datas.id = cards.datas.id)
WHERE (SELECT ot FROM cards.datas WHERE main.datas.id = cards.datas.id) is not null

或使用 coalesce():

UPDATE main.datas           
SET ot=coalesce((
  SELECT ot FROM cards.datas 
  WHERE main.datas.id = cards.datas.id AND cards.datas.ot IS NOT NULL
), ot);

【讨论】:

  • 感谢第一个有效,第二个无效。你能解释一下,这样我以后可以避免这种情况吗?
  • 第二个不起作用,因为我只是从您的问题中复制了它,而没有将 更改为 IS NOT。我编辑了。代码的作用是:只有在从表cards.datas 中找到NOT NULL 值时才会更新。如果为 NULL,则不会更新。
【解决方案2】:

典型的写法是使用not exists

UPDATE main.datas md         
    SET ot = (SELECT cd.ot
              FROM cards.datas cd
              WHERE md.id = cd.id AND cd.ot IS NOT NULL
             )
WHERE NOT EXISTS (SELECT cd.ot
                  FROM cards.datas cd
                  WHERE md.id = cd.id AND cd.ot IS NOT NULL
                 );

如果第一个子查询返回多行,这会产生错误风险。因此,您可能需要包含 LIMIT 1 或聚合函数。

【讨论】:

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