使用 CTE,比较具有相同 ID 的行并将最旧的行更新为 0 SQL Server 2008

With CTE, compare rows with same ID and updating oldest one to 0 SQL Server 2008

Asked for the logic yesterday, now I've worked a way around.

我有一个很大的 table 用于报告(170k~ 行),其中许多是 "duplicated" 但有更新的日期(例如旧记录说 John Doe worked from X to Y 而新记录说John Doe worked from X2 to Y2).

我想知道哪些是 oldnew 所以我设置了一个特殊的列来存储布尔值(默认 1) 所以当我 运行 我创建的 CTE 时,如果有多个具有相同 ID 的记录,则将旧值更改为 0。使用此 cte,我得到了 new record deleted 并且我试图将删除部分更改为 update the old record 但我收到错误 207因为列 valid 无效。

非常感谢对我的代码的任何帮助。

;with cte
    as (select Row_number() over (partition BY id_gen, perpro,valido order by ini desc) RN 
        from tstSolap)
delete from cte
--update cte set valido = 0
where RN > 1

只需将 valido 列包含在 CTE 中:

with cte as (
     select s.*,
            Row_number() over (partition BY id_gen, perpro,valido order by ini desc) RN 
     from tstSolap as s
)
update cte 
     set valido = 0
where RN > 1;

CTE 以某种方式知道识别更新或删除的行。

但要实际更新某个列,则还需要将其包含在 CTE 中。
对于 DELETE,这不是必须的。

然后您还可以只包含您在 ROW_NUMBER 中使用的其他字段。
这使得复制 CTE 的查询、在实际进行任何更改之前手动测试它变得更加容易。

此外,我怀疑您是否真的需要 PARTITION BY 中的 valido 来查找重复的 (id_gen, perpro) 元组。

WITH CTE AS
(
  SELECT 
   id_gen, perpro, ini, valido,
   ROW_NUMBER() OVER (PARTITION BY id_gen, perpro ORDER BY ini DESC) RN 
  FROM tstSolap
)
UPDATE CTE
SET valido = 0
WHERE RN > 1
  AND (valido IS NULL OR valido <> 0)

或者如果你想更正 0 或 1

WITH CTE AS
(
  SELECT 
   id_gen, perpro, ini, valido,
   IIF(ROW_NUMBER() OVER (PARTITION BY id_gen, perpro ORDER BY ini DESC) = 1, 1, 0) AS new_valido
  FROM tstSolap
)
UPDATE CTE
SET valido = new_valido
WHERE (valido != new_valido OR valido IS NULL)