【问题标题】:How to update a column base on another column's value from another table如何根据另一个表中另一列的值更新列
【发布时间】:2019-03-29 09:26:55
【问题描述】:

我有一个table A,有 2 个主要列:NameSettingsSettings 列将有 3 个值:1、2 或 3。

例如:

Name     Settings
Andre        1
Andre        1
Betty        3
Charles      1
Charles      1

注意1个Name只能有1个Settings:1、2或3

我还有另一个 table B,有 2 个主要列:NameTypeType 列包含许多值:'TypeA''TypeB''TypeC'......

例如:

Name       Type
Andre      TypeA
Andre      TypeA
Andre      TypeC
Betty      TypeB
Betty      TypeB
Charles    TypeB
Charles    TypeA
Charles    TypeA

请注意,1 个Name 可以有多个相同或不同的Type。我们只考虑TypeATypeB

现在我想使用来自table B'Type' 列从table A 更新Settings 列,如果:

  • table B 中的Type 列的值为'TypeA',然后将两个表中具有相同Name 的所有记录设置为table A 中的Settings 列上的1 @。
  • table B 中的Type 列的值为'TypeB',然后将两个表中具有相同Name 的所有记录设置为来自@9876543555 的Settings 列上的2 @。
  • table B 中的Type 列同时具有'TypeA''TypeB' 的值,然后将两个表中具有相同Name 的所有记录设置为@ 上的3 987654361@ 列来自table A

table A 的结果会变成这样:

Name     Settings
Andre        1
Andre        1
Andre        1
Betty        2
Charles      3
Charles      3

我该怎么做? 到目前为止我尝试过的:

UPDATE a
SET a.Settings = CASE b.Type 
                       WHEN 'TypeA' THEN 1
                       WHEN 'TypeB' THEN 2
                    END
FROM   tablsA a
JOIN   tableB b 
ON a.name = b.name
WHERE  type IN ('TypeA', 'TypeB')

【问题讨论】:

    标签: sql sql-server tsql sql-update


    【解决方案1】:

    解决此问题的不同方法。我会添加几列以使生活更轻松。之后,更新变得微不足道:

    USE TEMPDB
    
    CREATE TABLE A (Names VARCHAR (20), Sorts VARCHAR (20), A INT, B INT, AB INT)
    
    INSERT INTO A VALUES 
    ('Andre'   ,   'TypeA' ,0 ,0, 0),
    ('Andre'   ,   'TypeA' ,0 ,0, 0),
    ('Andre'   ,   'TypeC' ,0 ,0, 0),
    ('Betty'   ,   'TypeB' ,0 ,0, 0),
    ('Betty'   ,   'TypeB' ,0 ,0, 0),
    ('Charles' ,   'TypeB' ,0 ,0, 0),
    ('Charles' ,   'TypeA' ,0 ,0, 0),
    ('Charles' ,   'TypeA' ,0 ,0, 0) 
    
    UPDATE A
    SET A = 1 
    WHERE Sorts = 'TypeA'
      AND NOT EXISTS ( SELECT * FROM A AS A2
                    WHERE A.Names = A2.Names
                      AND A2.Sorts = 'TypeB' )
    
    UPDATE A
    SET B = 1 
    WHERE Sorts = 'TypeB'
      AND NOT EXISTS ( SELECT * FROM A AS A2
                    WHERE A.Names = A2.Names
                      AND A2.Sorts = 'TypeA' )
    
    UPDATE A
    SET AB = 1 
    WHERE Sorts = 'TypeA'
      AND  EXISTS ( SELECT * FROM A AS A2
                 WHERE A.Names = A2.Names
                   AND A2.Sorts = 'TypeB' )
    
    SELECT * FROM A
    

    -- 编辑:另一个选择是使用 CTE,因为 OP 不能更改或创建表。同样的事情,在添加额外的之后,您可以使用 CTE 进行更新。

    CREATE TABLE D (Names VARCHAR (20), Sorts VARCHAR (20))
    INSERT INTO D VALUES 
        ('Andre'   ,   'TypeA'),
        ('Andre'   ,   'TypeA'),
        ('Andre'   ,   'TypeC'),
        ('Betty'   ,   'TypeB'),
        ('Betty'   ,   'TypeB'),
        ('Charles' ,   'TypeB'),
        ('Charles' ,   'TypeA'),
        ('Charles' ,   'TypeA'); 
    
    WITH CTE AS 
    
    (
        SELECT *,
             CASE WHEN Sorts = 'TypeA' AND NOT EXISTS ( SELECT * FROM D AS D2
                                                    WHERE D.Names = D2.Names
                                                      AND D2.Sorts = 'TypeB' ) THEN 1 ELSE 0 END AS A,
              CASE WHEN Sorts = 'TypeB' AND NOT EXISTS ( SELECT * FROM D AS D2
                                                     WHERE D.Names = D2.Names
                                                       AND D2.Sorts = 'TypeA' ) THEN 1 ELSE 0 END AS B,
              CASE WHEN Sorts = 'TypeB' AND EXISTS ( SELECT * FROM D AS D2
                                                 WHERE D.Names = D2.Names
                                                   AND D2.Sorts = 'TypeA' ) THEN 1 ELSE 0 END AS AB
        FROM D
    )
    
    SELECT * FROM CTE 
    

    【讨论】:

    • 嗨,我无法编辑 table A 结构。你能做到不改变结构吗?
    • @VũTrần 我添加了一个额外的选项,使用公用表表达式。
    • @VũTrần 有用吗?如果是这样,请接受这个答案。
    • 您好,感谢您的贡献。完成了:)
    【解决方案2】:

    这是我的方法!我已经为三种不同的类型更新了三次TableA

    见以下代码:

    UPDATE TableA SET TableA.Settings = 1
    WHERE Exists(
      SELECT 1 FROM TableB B
      WHERE TableA.Name = B.Name
      AND B.Type = 'TypeA'
    )
    
    UPDATE TableA SET TableA.Settings = 2
    WHERE Exists(
      SELECT 1 FROM TableB B
      WHERE TableA.Name = B.Name
      AND B.Type = 'TypeB'
    )
    
    UPDATE TableA SET TableA.Settings = 3
    WHERE Exists(
      SELECT 1 FROM TableB B1
      INNER JOIN TableB B2
      ON(B1.Name = B2.Name AND B1.Type != B2.Type)
      WHERE TableA.Name = B1.Name
      AND ((B1.Type = 'TypeA' AND B2.Type = 'TypeB')
        OR (B1.Type = 'TypeB' AND B2.Type = 'TypeA'))
    )
    

    Here is the working demo!

    希望对您有所帮助。

    【讨论】:

      【解决方案3】:
      WITH CTE
      AS (
          SELECT NAME
              ,COUNT(DISTINCT TYPE) CNO
          FROM TABLEB
          WHERE TYPE <> 'TYPEC'
          GROUP BY NAME
          )
      UPDATE A
      SET Settings = CASE 
              WHEN T.Type = 'TypeA'
                  AND C.CNO = 1
                  THEN 1
              WHEN T.Type = 'TypeB'
                  AND C.CNO = 1
                  THEN 2
              WHEN C.CNO = 2
                  THEN 3
              END
      FROM TABLEA AS A
      INNER JOIN CTE AS C ON A.NAME = C.NAME
      INNER JOIN (
          SELECT DISTINCT NAME
              ,TYPE
          FROM TABLEB
          WHERE TYPE <> 'TYPEC'
          ) T ON A.NAME = C.NAME
      

      【讨论】:

      • 嗨,实际上,对于Type 列,除了Type A'Type B''Type C' 之外,还有更多的值,所以在 CTE 中它可能不起作用:(
      【解决方案4】:

      试试这个

      select * into #table1 from ( SELECT 'Andre' AS Name ,1 AS 设置 UNION ALL SELECT 'Andre' ,1 UNION ALL SELECT '贝蒂' ,3 UNION ALL SELECT '查尔斯' ,1 UNION ALL SELECT '查尔斯' ,1 )XX

      select * into #table2 from ( SELECT 'Andre' AS Name ,'TypeA' AS 键入 UNION SELECT 'Andre' ,'TypeA' UNION SELECT 'Andre' ,'TypeC' UNION SELECT 'Betty' ,'TypeB' UNION SELECT 'Betty' ,'TypeB' UNION SELECT 'Charles' ,'TypeB' UNION SELECT 'Charles' ,'TypeA' UNION 选择'查尔斯','TypeA')YY

      UPDATE XX SET XX.Setting = CASE 何时存在(
      选择
      1 从 #table2 YY 在哪里 YY.Name = XX.Name AND YY.Type = 'TypeA'

                                        EXCEPT 
      
                                        SELECT  
                                            1
                                        FROM
                                            #table2 YY
                                        WHERE 
                                            YY.Name = XX.Name
                                            AND YY.Type = 'TypeB'
                                        ) THEN 1
                        WHEN EXISTS(            
                                        SELECT  
                                            1
                                        FROM
                                            #table2 YY
                                        WHERE 
                                            YY.Name = XX.Name
                                            AND YY.Type = 'TypeB'
      
                                        EXCEPT 
      
                                        SELECT  
                                            1
                                        FROM
                                            #table2 YY
                                        WHERE 
                                            YY.Name = XX.Name
                                            AND YY.Type = 'TypeA'
                                        ) THEN 2
                        WHEN EXISTS(            
                                        SELECT  
                                            1
                                        FROM
                                            #table2 YY
                                        WHERE 
                                            YY.Name = XX.Name
                                            AND YY.Type = 'TypeA'
      
                                        INTERSECT 
      
                                        SELECT  
                                            1
                                        FROM
                                            #table2 YY
                                        WHERE 
                                            YY.Name = XX.Name
                                            AND YY.Type = 'TypeB'
                                        ) THEN 3
                    END                                                       FROM  #table1 XX
      

      【讨论】:

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