【问题标题】:Update with Join in SQLite在 SQLite 中使用 Join 更新
【发布时间】:2013-10-09 11:03:35
【问题描述】:

我有 2 个表,我想用另一个表的值更新其中一个。

software
---------
id ,
purchprice

softwarecost
------------
id ,
purchprice

我已经尝试过这些查询,但是 SQLite 不支持通过 UPDATE 进行 JOINS。任何人都可以对此提出查询。感谢您的帮助。

UPDATE software 
SET software.purchprice=softwarecost.purchprice 
WHERE software.id=softwarecost.id

UPDATE software 
INNER JOIN softwarecost on software.id=softwarecost.id 
SET software.purchprice=softwarecost.purchprice 

【问题讨论】:

  • sqlite当然支持join。
  • 不是 UPDATE.thanks
  • @Carter 如果提供的答案之一解决了您的问题,请单击它旁边的复选标记以表明问题已解决。

标签: sqlite


【解决方案1】:

这会起作用

UPDATE 
      software
SET purchprice = (SELECT purchprice
                  FROM softwarecost
                  WHERE id = software.id) 
where EXISTS (SELECT purchprice
                  FROM softwarecost
                  WHERE id = software.id)

这里我们使用存在,因为 如果没有找到“相关”行,则查询会将 software.purchprice 设置为 null。

【讨论】:

【解决方案2】:

您必须使用相关子查询查找相应的值:

UPDATE software
SET purchprice = (SELECT purchprice
                  FROM softwarecost
                  WHERE id = software.id)

【讨论】:

  • 但请注意,这会将software.purchprice 设置为null,其中在softwarecost 中找不到“相关”行。
  • @Colin'tHart 这似乎是我们想要的行为,不是吗?
  • 我刚试过这个。整个表格软件中的字段purchprice 将具有相同的值。它没有加入。
  • SQLite3 似乎不支持 WHEREstatements 引用数据库中的其他表(我正在运行与上面类似的代码并收到错误 Error: no such column: software.id)。有任何线索还是我应该提出一个新问题?
  • @lmrta 您只能引用 UPDATE 或 SELECT 使用的表。
【解决方案3】:

这个语句可以正常工作!

它只会更新“softwarecost”中具有相同 ID 的“software”中的行!

UPDATE software SET software.purchprice = 
     (SELECT purchprice FROM softwerecost WHERE software.id = softwerecost.id) 
     WHERE id IN (SELECT id FROM softwarecost);

另一种方法:

DELETE FROM software WHERE id IN (SELECT id FROM softwarecost);
INSERT INTO software SELECT * FROM softwarecost;

...如果您必须更新所有列(如果您有更多列要更新),这种方式会更方便

【讨论】:

    【解决方案4】:

    我刚刚找到了这个,使用UPSERT

    INSERT INTO software (id, purchprice)
    SELECT a.id, b.purchprice FROM software AS a INNER JOIN softwarecost AS b ON a.id=b.id
    ON CONFLICT(id) DO UPDATE SET purchprice=excluded.purchprice
    

    这只有在你有的时候才有效

    • SQLite 版本 3.24.0 或更高版本和
    • software.id 上的唯一约束,例如通过将其定义为主键。

    它不需要潜在的慢相关子查询,并且可以处理多列更新。

    【讨论】:

    • 你在哪里被“排除”。从?
    • 这是一个保留的伪表,由 UPSERT 语法自动提供。请参阅链接的 SQLite 文档:“DO UPDATE 表达式中的列名指的是在尝试插入之前该列的原始未更改值。要使用在约束未失败的情况下将插入的值,请添加特殊的”排除。" 列名的表限定符。"
    【解决方案5】:

    我知道这是旧的,但我更喜欢

    UPDATE software
    SET purchprice = IFNULL( (SELECT purchprice
                              FROM softwarecost
                              WHERE id = software.id), purchprice) 
    

    它可以作为 UPDATE with JOIN 问题的通用解决方案,并且使 SQLite 不必执行第二个 SELECT 语句来验证子查询中是否确实存在一行。

    【讨论】:

    • 这个解决方案更短,不会重复查询。但是,我对两者都进行了测试,由于某种原因,这一个比带有“WHERE EXISTS”的那个慢几个数量级。因此,仅在速度无关紧要时使用。
    • 如果 purchprice 列中很少有 NULL 并且表非常大,因为 SQL 必须在不需要时进行大量搜索值,这实际上是有意义的。因此,这取决于您的数据集是您预计大部分是 NULL 还是大部分已经填写的值。如果您已经填写了大部分值并且表很大,那么您使用这种格式的 SQL 会受到打击。如果表很小,或者purchprice列中大部分为NULL,或者可维护性是SQL语句的主要关注点,那么使用这种格式的SQL。
    • 这当然是我的情况(大表只有几行更新了值)。所以当然这可能取决于数据组合。
    • 我将对此再添加一条评论。在实践中,通常存在一些其他条件来减少更新语句将查看的值集,例如今天创建的所有记录或将在更新语句本身的 where 子句中指定的特定批次号以减少更新语句将查看的行数。然后,它可以与 WHERE EXISTS 版本大致一样高效,但更易于维护。
    【解决方案6】:

    这里的其他答案大多是正确的,但需要稍作改动。至少我当然需要对其进行更改才能使其正常工作。不确定这是多年来发生的对 SQLite 的更改,还是只是它从未在这里被捕获,但您需要完全限定 softwarecost 中对列 id 的引用在 WHERE 子句中为 @987654324 @ 而不仅仅是WHERE id = software.id。如果不这样做,我刚刚运行的查询使所有条目都具有相同的值,并且它是第一个链接的值——这意味着software.purchprice 的所有条目都与softwarecost.purchprice 中的第一个条目相同。我认为这是由于 id 列不明确,如果它只是“id=software.id”,因此会自行链接。

    UPDATE 
          software
    SET purchprice = (SELECT purchprice
                      FROM softwarecost
                      WHERE softwarecost.id = software.id) 
    where EXISTS (SELECT purchprice
                      FROM softwarecost
                      WHERE softwarecost.id = software.id)
    

    【讨论】:

      【解决方案7】:

      Carter,>>near "s": syntax error

      【讨论】:

        【解决方案8】:

        使用 Pelle Jacobs 在评论中建议的新的 UPDATE FROM 语法。

        UPDATE software
        SET purchprice = c.purchprice
        FROM (SELECT purchprice FROM softwarecost) AS c
        WHERE c.id = software.id;
        

        【讨论】:

          【解决方案9】:
          Update software 
            set Column1 = anyValue
            where id in (Select sf.id from software sf join softwarecost  sfc on sf.id=sfc.id
              where sfc.purchprice='anyValue' 
            )
          

          如果您要使用 Join 和 Where 条件更新什么

          【讨论】:

            【解决方案10】:

            你可以试试,

            UPDATE software SET purchprice = (SELECT purchprice FROM softwarecost a WHERE a.id =software.id) where purchprice IN(SELECT distinct(purchprice) FROM softwarecost a WHERE a.id = software.id)
            

            【讨论】:

              【解决方案11】:

              这里没有JOIN:

              UPDATE software
              SET software.purchprice=softwarecost.purchprice
              WHERE software.id=softwarecost.id
              

              这不起作用:

              UPDATE software s INNER JOIN softwarecost sc on s.id=sc.id
              SET s.purchprice=sc.purchprice 
              

              SQLite 确实不支持 UPDATE 查询中的 JOIN http://sqlite.org/lang_update.html

              使用 REPLACE 怎么样?
              也许你可以:

              REPLACE INTO software
              SELECT id, purchprice
              FROM softwarecost
              

              【讨论】:

              • 您好 Bogdan 感谢您的回复,我收到了这个错误。 SQLiteManager:可能的 SQL 语法错误:UPDATE software s INNER JOIN softwarecost sc on s.id=sc.id SET s.purchprice=sc.purchprice [靠近“s”:语法错误] 异常名称:NS_ERROR_FAILURE
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-08-02
              • 2010-12-08
              • 2014-01-24
              • 1970-01-01
              • 2014-11-30
              • 2015-11-05
              相关资源
              最近更新 更多