【问题标题】:A conditional SQL update statement for two tables at once一次针对两个表的条​​件 SQL 更新语句
【发布时间】:2011-09-15 19:07:17
【问题描述】:

我想一次更新两个表。下面的代码似乎工作正常。但是,在某些情况下,bidGroups 中没有条目,这意味着整个语句将失败。如何调整它以更新第一位(watchedItems)并且如果 watchItems.bidGroupID 为空则不尝试第二部分

UPDATE watchedItems, bidGroups 
SET watchedItems.won=1, bidGroups.bidGroupQty=bidGroups.bidGroupQty-1 
WHERE watchedItems.id=2 
AND watchedItems.aid=200618152822 
AND bidGroups.bidGroupID=watchedItems.bidGroupID 
AND bidGroups.id=2;

我试过了,但是语法错误..

UPDATE  watchedItems, bidGroups 
SET watchedItems.won=1, 
CASE WHEN watchedItems.bidGroupID IS NOT NULL THEN bidGroups.bidGroupQty=bidGroups.bidGroupQty-1 
ELSE END
WHERE watchedItems.id=2 
AND watchedItems.aid=200618152822 
AND bidGroups.bidGroupID=watchedItems.bidGroupID 
AND bidGroups.id=2

【问题讨论】:

    标签: mysql sql conditional


    【解决方案1】:

    你只需要left outer join就可以了。

    update watchedItems wi left outer join bidGroups bg
     on wi.bidGroupID = bg.bidGroupID
     set
      wi.won = 1,
      bg.bidGroupQty = bg.bidGroupQty - 1
     where wi.id = 2
     and wi.aid = 200618152822
     and (bg.id = 2 or bg.id is null)
    

    如果watchedItems.bidGroupId 为空,那么它只会更新watchedItems 中找到的行,因为在bidGroups 中没有可加入的内容。如果不是,并且连接在两个表中都获取了行,那么对两个表的更新都会正常进行。

    仅使用watchedItems, bidGroupsinner join 相同,因此当bidGroups 中没有要加入的条目时,您也不会从watchedItems 获得结果。在select 上使用相同的joinwhere 子句而不是update,您会看到不同之处:

    select wi.won, bg.bidGroupQty
     from watchedItems wi, bidGroups bg
     where wi.id = 2 and wi.aid = 200618152822
     and (bg.id = 2 or bg.id is null)
     and wi.bidGroupID = bg.bidGroupID
    

    对比:

    select wi.won, bg.bidGroupQty
     from watchedItems wi left outer join bidGroups bg
     on wi.bidGroupID = bg.bidGroupID
     where wi.id = 2 and wi.aid = 200618152822
     and (bg.id = 2 or bg.id is null)
    

    【讨论】:

    • 我认为这不起作用,因为如果bidGroups 没有 ID = 2 的条目,WHERE 子句中的条件“bg.id = 2”将不会产生任何结果;没有结果将意味着不会运行更新
    • 阿贝是对的。我尝试了所有这些,不幸的是它们在语法上被接受但没有返回任何结果。非常感谢您的努力和解释,非常感谢!!!
    • 好点。只需 OR 对 null 进行检查,这样它就可以处理右侧没有结果的情况。但是 Abhay 将该条件放在 ON 子句中的方式更简洁。
    【解决方案2】:

    以这种方式尝试 LEFT JOIN:

    UPDATE watchedItems 
    LEFT JOIN bidGroups ON watchedItems.bidGroupID = bidGroups.bidGroupID AND bidGroups.id=2
    SET watchedItems.won=1, bidGroups.bidGroupQty=bidGroups.bidGroupQty-1 
    WHERE watchedItems.id=2 
    AND watchedItems.aid=200618152822;
    

    ......

    【讨论】:

    • 就是这样。完美运行。非常感谢阿贝。现在是我学习 JOIN 的时候了 :-)
    【解决方案3】:

    如果您不想更改,只需将其设置为当前值即可。 MySQL 通常通过在值相同时不更新它来优化它。

    UPDATE watchedItems 
      LEFT JOIN bidGroups ON bidGroups.bidGroupID=watchedItems.bidGroupID 
           AND bidGroups.id=2
    SET watchedItems.won=1, 
        bidGroups.bidGroupQty= if(watchedItems.bidGroupID IS NULL, 
                                  bidGroups.bidGroupQty, 
                                  bidGroups.bidGroupQty-1)
    WHERE watchedItems.id=2 
    AND watchedItems.aid=200618152822;
    

    但是,您不需要if,因为如果watchedItems.bidGroupID IS NULL 则不会加入来自bidGroups 的行,并且忽略该不存在行的更新。 所以bidGroups.bidGroupQty=bidGroups.bidGroupQty-1 就好了

    【讨论】:

    • 我喜欢这个主意。但是,当我尝试它并且在bidGroups 表中没有条目时,它也不会影响watchedItems 表?! :-(
    • ,inner join 相同,这就是原因。我在回答中添加了一些解释。
    猜你喜欢
    • 2016-12-21
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 2018-03-11
    • 2011-01-03
    • 1970-01-01
    • 2018-09-11
    • 2016-04-02
    相关资源
    最近更新 更多