多条件多更新

Rew*_*ind 5 mysql update

我们被告知要通过使用以下 IN 子句来注意设置为 null(我们不想要)的东西:

UPDATE Tests SET
     TestScore =
              CASE
                  WHEN TestId = 10 THEN 1000
                  WHEN TestId = 11 THEN 1100
              END,
     TestScore2 =
              CASE
                  WHEN TestId = 10 THEN 2000
                  WHEN TestId = 11 THEN 2100
              END
     WHERE TestId IN (10, 11)
Run Code Online (Sandbox Code Playgroud)

但是当需要两个条件时会发生什么,即 (TestId, TestSubId) 的联合组合?即,我如何对 IN 子句 ???,在下面显示它必须在组合 (10,25) 和 (11,22) 中:

UPDATE Tests SET
    TestScore = CASE
        WHEN (TestId = 10 AND TestSubId = 25) THEN 1000
        WHEN (TestId = 11 AND TestSubId = 22) THEN 1100
    END,
    TestScore2 = CASE
        WHEN (TestId = 10 AND TestSubId = 25) THEN 2000
        WHEN (TestId = 11 AND TestSubId = 22) THEN 2100
    END
    WHERE TestId, TestSubId IN ?????
Run Code Online (Sandbox Code Playgroud)

And*_*y M 6

在 MySQL 中,您可以使用元组比较:

WHERE (TestId, TestSubId) IN ((10,25), (11,22))
Run Code Online (Sandbox Code Playgroud)

这看起来不错而且简洁,不过,就像ypercube??在评论中提到,它在性能方面可能效果不佳。

但是,考虑到如何在 UPDATE 语句中重新使用条件,您也可以完全采用不同的方法:将受影响的 ID 和新值表示为派生表,并使用带有连接的更新:

UPDATE
    Tests AS old
    INNER JOIN
    (
        SELECT 10 AS TestId, 25 AS TestSubId, 1000 AS TestScore, 2000 AS TestScore2
        UNION ALL
        SELECT 11, 22, 1100, 2100
    ) AS new
    ON old.TestId = new.TestId AND old.TestSubId = new.TestSubId
SET
    old.TestScore  = new.TestScore,
    old.TestScore2 = new.TestScore2
;
Run Code Online (Sandbox Code Playgroud)

这样,new派生表既充当Tests更新的新值的过滤器,又充当新值的提供者。