【问题标题】:How to update every single row of a column based on a condition in another table如何根据另一个表中的条件更新列的每一行
【发布时间】:2022-11-10 18:54:32
【问题描述】:

我有一张桌子 A

aId    aCode
1      ABC
2      DEF
3      GHI

..和B表

bId    bCode
1      JKL
2      MNO
3      PQR

在 C 表中,如果 cCode 在 A 或 B 表中,我应该更新列“inAorB”,因此它看起来像这样:

cId    cCode inAorB
1      ABC    A
2      GHI    A
3      PQR    B

.. 现在 C 看起来像这样:

cId    cCode inAorB
1      ABC    NULL
2      GHI    NULL
3      PQR    NULL

它应该更新所有行。

【问题讨论】:

  • 如果代码同时在 A 和 B 中怎么办? Id 还需要匹配还是只匹配代码?
  • 不,假设它不能同时存在

标签: sql-server tsql sql-update


【解决方案1】:

您可以对每个源表执行LEFT JOIN,然后使用CASE 来确定哪一个产生匹配。由于CASE 是按顺序计算的,因此如果您必须处理两个表中的代码,您还可以使用它来决定优先考虑哪个表。

UPDATE c
SET inAorB = CASE 
               WHEN a.aCode IS NOT NULL THEN 'A'
               WHEN b.bCode IS NOT NULL THEN 'B'
               ELSE NULL
             END
FROM
  c
LEFT JOIN
  a
    ON a.aID = c.cID
    AND a.aCode = c.cCode
LEFT JOIN
  b
    ON b.bID = c.cID
    AND b.bCode = c.cCode;

【讨论】:

  • 我要求澄清,但我认为xID 值不需要匹配(查看GHI)。
【解决方案2】:

要重现您的代码,您可以这样做:

CREATE TABLE #A
(
    [aId] INT,
    [aCode] VARCHAR(MAX)
)

INSERT INTO #A VALUES
    (1, 'ABC'),
    (2, 'DEF'),
    (3, 'GHI')

CREATE TABLE #B
(
    [bId] INT,
    [bCode] VARCHAR(MAX)
)

INSERT INTO #B VALUES
    (1, 'JKL'),
    (2, 'MNO'),
    (3, 'PQL')

CREATE TABLE #C
(
    [cId] INT,
    [cCode] VARCHAR(MAX),
    [inAorB] CHAR(1)
)

INSERT INTO #C VALUES
    (1, 'ABC',NULL),
    (2, 'GHI',NULL),
    (3, 'PQR',NULL)

-- The script you are interested in
UPDATE C
SET [inAorB] = CASE
                    WHEN A.aId IS NOT NULL THEN 'A'
                    WHEN B.bId IS NOT NULL THEN 'B'
                    ELSE NULL
                END
FROM #C AS C
LEFT JOIN #A AS A ON A.aCode = C.cCode
LEFT JOIN #B AS B ON B.bCode = C.cCode
-- END

SELECT * FROM #C

DROP TABLE #A
DROP TABLE #B
DROP TABLE #C

如果两者都不为空,将设置“A”

【讨论】:

    【解决方案3】:

    如果条件为真,您可以使用CASE 表达式应用特定结果。请注意,如果代码可以同时出现在 A 和 B 中,则将选择 A。

    UPDATE C SET inAorB = CASE
      WHEN EXISTS (SELECT 1 FROM dbo.A WHERE A.aCode = C.cCode) THEN 'A' 
      WHEN EXISTS (SELECT 1 FROM dbo.B WHERE B.bCode = C.cCode) THEN 'B' 
      ELSE '?' -- in case of no match
    END
    FROM dbo.C AS C;
    

    工作示例in this fiddle。请注意,抽象为EXISTS 将避免您在LEFT JOINs 中发现的不必要的排序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-04-17
      • 2019-08-20
      • 1970-01-01
      • 1970-01-01
      • 2022-12-12
      • 1970-01-01
      • 1970-01-01
      • 2011-11-25
      相关资源
      最近更新 更多