根据与CTE的联接更新列值

时间:2019-12-05 22:10:51

标签: sql sql-server

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

我有此帮助程序表:

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子句中完成?最好的和最简单的解决方案是基于另一个助手表的联接来更新列?

2 个答案:

答案 0 :(得分:2)

要使查询正常工作,您只需将JOINUsers的值从StateMatch State_shortABR

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

答案 1 :(得分:0)

首先:您实际上不需要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