С помощью CTE сравнивайте строки с одинаковым идентификатором и обновляя самый старый до 0 SQL Server 2008 - PullRequest
0 голосов
/ 30 января 2019

Спросил вчера о логике, теперь я обошел все вокруг.

У меня есть большая таблица, используемая для отчетов (170k ~ строк), и многие из них "продублированы"«но с обновленными датами (например, старая запись говорит John Doe worked from X to Y, а новая говорит John Doe worked from X2 to Y2).

Я хочу знать, какие из них старые и новые поэтому я установил специальный столбец, в котором хранятся логические значения (по умолчанию 1), поэтому при запуске созданного мной CTE, если существует несколько записей с одинаковым идентификатором, измените старое значение на 0.С помощью этого cte я удаляю новую запись и пытаюсь изменить удаляемую часть на обновить старую запись , но я получаю ошибку 207, потому что столбец valid isn 't действителен.

Любая помощь с моим кодом приветствуется.

;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

Ответы [ 2 ]

0 голосов
/ 30 января 2019

CTE каким-то образом знает, как идентифицировать строки для ОБНОВЛЕНИЯ или УДАЛЕНИЯ.

Но чтобы на самом деле ОБНОВИТЬ определенный столбец, вам также необходимо включить его в CTE.
Для УДАЛЕНИЯ это не обязательно.

И тогда вы могли бы также просто включитьдругие поля, которые вы используете в этом ROW_NUMBER.
Это облегчает копирование запроса CTE, тестирование его вручную перед внесением каких-либо изменений.

Кроме того, я сомневаюсь, что вам действительно нужно valido вPARTITION BY для поиска дубликатов (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)
0 голосов
/ 30 января 2019

Просто включите этот столбец 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...