具有 CTE 更新的 UPDATE 表始终具有相同的值

Posted

技术标签:

【中文标题】具有 CTE 更新的 UPDATE 表始终具有相同的值【英文标题】:UPDATE Table with CTE update always with the same value 【发布时间】:2022-01-06 10:16:25 【问题描述】:

我正在尝试通过数据洗牌匿名化数据库中的单个列。

我创建了这个查询,但是当我运行它时,它总是使用相同的名称更新列 FirstName

BEGIN TRAN;

;WITH TCE_Shuffled
AS (
    SELECT ROW_NUMBER() OVER (
            ORDER BY [BusinessEntityID]
            ) AS ORIG_ROWNUM
        ,ROW_NUMBER() OVER (
            ORDER BY NEWID()
            ) AS NEW_ROWNUM
        ,*
    FROM [AdventureWorks2014].[Person].[Person]
    )
UPDATE [AdventureWorks2014].[Person].[Person]
SET FirstName = t2.FirstName
FROM TCE_Shuffled t1
JOIN TCE_Shuffled t2 ON t1.ORIG_ROWNUM = t2.NEW_ROWNUM

SELECT *
FROM [AdventureWorks2014].[Person].[Person]

ROLLBACK TRAN

SELECT *
FROM [AdventureWorks2014].[Person].[Person]

在这里你可以看到FirstName列的值是一样的:

BusinessEntityID PersonType NameStyle Title FirstName MiddleName LastName
13353 IN 0 NULL Erik M Griffin
13354 IN 0 NULL Erik NULL Diaz
13355 IN 0 NULL Erik J Xu
13356 IN 0 NULL Erik NULL Sun
13357 IN 0 NULL Erik NULL Zhu
13358 IN 0 NULL Erik R Gao
13359 IN 0 NULL Erik NULL Hayes
13360 IN 0 NULL Erik NULL Ma
13361 IN 0 NULL Erik G Price
13362 IN 0 NULL Erik M Liang

我做错了什么?

【问题讨论】:

讨厌:The semicolon (;) is a statement terminator不是一个“初学者”。它位于 all 语句的 end 处,而不是需要正确终止 previous 语句的语句的开头。不正确终止语句已被弃用,因此您现在应该真正尝试养成正确终止语句的习惯,以便在每次强制更改时您的代码不会中断。 我不知道。我在网上看到很多这样的查询。我会分享这个提示,谢谢拉努 是的,很多人在网上发帖时把它放在 CTE 的开头,因为写(在我看来)糟糕的 SQL 副本的人说代码然后抱怨它是错误的并且不起作用,在哪里因为错误的实际代码是复制它的人。 您遇到问题的原因是您再次与 UPDATE [AdventureWorks2014].[Person].[Person] 交叉加入所有内容,因为您没有提到 FROM 子句 @forpas 给了你正确的答案,我只是在解释问题的根本原因 【参考方案1】:

这是UPDATE 语句的正确语法:

UPDATE t1
SET t1.FirstName = t2.FirstName
FROM TCE_Shuffled t1 JOIN TCE_Shuffled t2 
ON t1.ORIG_ROWNUM = t2.NEW_ROWNUM;

【讨论】:

这太神奇了。祝你有美好的一天

以上是关于具有 CTE 更新的 UPDATE 表始终具有相同的值的主要内容,如果未能解决你的问题,请参考以下文章

ListView 始终具有相同的意图

SQL Server 公用表表达式(CTE)实现递归

SQL Server 公用表表达式(CTE)实现递归

在 MySQL 中使用 CTE 更新或删除

从具有某些条件的两个相同表中获取记录

递归 CTE 通过多个级别更新父记录