【问题标题】:Update Column values based on join with CTE基于与 CTE 连接的更新列值
【发布时间】:2019-12-05 22:10:51
【问题描述】:

我目前正在学习如何在 SQL Server 2016 中使用 CTE,因为我有一些大表,我需要根据帮助列的匹配来更新一些列,我不完全确定它是如何完成的。我知道这也可以通过经典更新来完成,因为我现在想以 CTE 的方式学习和理解它,因为它会在不久的将来派上用场。

我有这个 Helper 表:

State      ABR
Alabama    AL
Alaska     AK
Arizona    AZ

我需要根据 state_short 和 ABR 之间的连接填写 State 列。

User    State_short State
John    AL          NULL
Carl    AK          NULL
Ivan    AZ          NULL
Martin  AZ          NULL
William AK          NULL
Sean    AL          NULL
Bob     AL          NULL

我试过这段代码:

WITH StateMatch AS 
(
SELECT [State] AS StateName, [ABR] FROM [States]
)
UPDATE [Users]
SET [State] = StateName
FROM StateMatch

但这只会给我这个输出:

User    State_short State
John    AL   Alabama
Carl    AK   Alabama
Ivan    AZ   Alabama
Martin  AZ   Alabama
William AK   Alabama
Sean    AL   Alabama
Bob     AL   Alabama

我可以看到,我缺少一个连接,但我不确定如何使用 CTE - 它是在 CTE 中完成的,还是在下面的 select 子句中完成的,还是可以通过 where 子句完成?根据来自另一个帮助表的联接更新列的最佳和最简单的解决方案是什么?

【问题讨论】:

    标签: sql sql-server


    【解决方案1】:

    要使您的查询正常工作,您只需在 State_shortABR 值上将 JOIN UsersStateMatch

    WITH StateMatch AS 
    (
    SELECT [State] AS StateName, [ABR] FROM [States]
    )
    UPDATE [Users]
    SET [State] = StateName
    FROM [Users] u
    JOIN [StateMatch] s ON u.[State_short] = s.[ABR]
    

    然后你可以:

    SELECT *
    FROM Users
    

    输出

    User        State_short     State
    John        AL              Alabama
    Carl        AK              Alaska
    Ivan        AZ              Arizona
    Martin      AZ              Arizona
    William     AK              Alaska
    Sean        AL              Alabama
    Bob         AL              Alabama
    

    Demo on SQLFiddle

    【讨论】:

      【解决方案2】:

      首先:您实际上并不需要 CTE。您可以只使用相关子查询:

      update Users
      set State = (
          select s.State from States s where s.ABR = Users.State_short
      )
      where State is null
      

      如果您真的想使用 CTE,另一种选择是在 CTE 内join,然后更新 CTE。 SQLServer 具有惊人的能力来回溯事物并将更改应用到基础表列:

      with cte as (
          select u.State, s.State New_state
          from Users u
          inner join States s on s.ABR = u.State_short
      )
      update cte set State = New_state
      

      Demo on DB Fiddle

      【讨论】:

        猜你喜欢
        • 2016-06-21
        • 2017-12-15
        • 1970-01-01
        • 2013-01-21
        • 1970-01-01
        • 1970-01-01
        • 2023-02-14
        • 2010-12-31
        相关资源
        最近更新 更多