使用 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
).
我想知道哪些是 old 和 new 所以我设置了一个特殊的列来存储布尔值(默认 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)
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
).
我想知道哪些是 old 和 new 所以我设置了一个特殊的列来存储布尔值(默认 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)