Копирование данных из строк в одной таблице, если они удовлетворяют нескольким условиям

#sql #sql-server

#sql #sql-сервер

Вопрос:

У меня есть таблица, которая выглядит следующим образом

ID C1 C2 C3 C4 Дата
101 1 1 1 1 01/01/2020
101 1 1 2 2 01/03/2020
101 1 2 3 01/05/2020
101 2 3 4 3 01/07/2020
201 1 1 1 1 02/02/2020
201 1 1 2 2 02/04/2020
201 1 2 3 02/06/2020
201 2 3 4 3 02/08/2020

Что мне нужно сделать, это изменить столбец даты на ID = 201, чтобы он соответствовал ID = 101. Столбцы C1: C4 используются для идентификации строк. Так, например, последняя строка с датой = 02/08/2020 должна быть изменена на 01/07/2020, поскольку оба их C1: C4 одинаковы.

Столбец C4 может иметь значения null, но другие 3 столбца не будут иметь значения null. Для каждой записи в ID = 101 будет соответствующая запись в ID = 201 с одинаковыми значениями для C1: C4. Каждая комбинация C1: C4 будет уникальной.

Я пытался искать примеры с инструкциями SQL UPDATE, но не смог найти ни одного, который соответствовал бы моему случаю, поэтому буду признателен за любую помощь! Спасибо

ОБНОВЛЕНИЕ: следующий код работал для обработки нулевых значений

 set t2.date = t1.date
from t t1 join t t2
ON CONCAT(t1.c1,t1.c2,t1.c3,t1.c4) = CONCAT(t2.c1,t2.c2,t2.c3,t2.c4)
where t1.id = 101 and t2.id = 202
 

Комментарии:

1. UPDATE с JOIN помощью , для обработки значений с нулевыми значениями, подзапрос с INTERSECT

Ответ №1:

Вы можете использовать update with join . Один из методов:

 update t2
    set t2.date = t1.date
    from t t1 join
         t t2
         on t1.c1 = t2.c1 and t1.c2 = t2.c2 and t1.c3 = t2.c3 and t1.c4 = t2.c4
    where t1.id = 101 and t2.id = 202;
 

Если c4 может быть NULL ,

 update t2
    set t2.date = t1.date
    from t t1 join
         t t2
         on t1.c1 = t2.c1 and t1.c2 = t2.c2 and t1.c3 = t2.c3 and
            (t1.c4 = t2.c4 or t1.c4 is null and t2.c4 is null)
    where t1.id = 101 and t2.id = 202;
 

Комментарии:

1. Спасибо! Это работало только для тех строк, где C4 не было null . Поэтому я изменил оператор ON на ON CONCAT(t1.c1, t1.c2, t1.c3, t1.c4) = CONCAT(t2.c1, t2.c2, t2.c3, t2.c4), и это, казалось, сделало свое дело!

2. @GordonLinoff подумал, что вы достаточно хорошо знаете, чтобы использовать этот синтаксис для нулевых значений : on exists (select t1.c1, t1.c2, t1.c3, t1.c4 intersect t2.c1, t2.c2, t2.c3, t2.c4) .

3. @ponnob Это будет очень slow.as он не будет использовать индексы

4. @Charlieface . , , Это будет использовать индекс (c1, c2, c3) напрямую и будет использовать другие столбцы, если они есть в индексе.

5. Но если c4 это ключевой столбец, он не будет использовать его для поиска, в то время как мое решение использует.