Обновите SQL-строку в той же таблице с данными из другой строки

#sql #sql-server #sql-update

Вопрос:

Я застрял с выполнением SQL-запроса для обновления разных строк, все в одной таблице. Но 1 строка должна получать данные из другой строки, которая имеет тот же идентификатор ссылки ( bst__ref ).

ТЕКУЩАЯ ТАБЛИЦА bstlyn__

A B C D E F G
157035 1/01/1980 2/04/2021 117210 N 0 N
157035 1/01/1980 25/03/2021 128078 N 0 N
157035 1/01/1980 25/03/2021 128078 N 0 N
157036 1/01/1980 12/04/2021 117022 N 0 N
157036 1/01/1980 12/04/2021 117034 N 0 N
157036 1/01/1980 9/04/2021 128078 N 0 N

ТЕКУЩИЙ SQL-ЗАПРОС

 UPDATE bstlyn__ SET G = 'Y', F = 'N', B = C WHERE E = 'N' AND F = '0'
 

Это приводит к изменению всех vrz__dat строк на то же значение, что и в vrzv_dat . Но , как вы можете видеть внутри того же bst__ref , vrzv_dat всех afg__ref со значением 128078 имеет другое vrzv_dat значение . Это должна быть та же дата/ vrz__dat как (первая) строка из той bst__ref , в которой нет afg__ref 128078.

Итак, после выполнения приведенного выше запроса я получаю:

bst__ссылка (A) vrz__dat (B) vrzv_dat (C) afg__ссылка (D) fiat____ (E) fac__tst (F) vrz__tst (G)
157035 2/04/2021 2/04/2021 117210 N N Y
157035 25/03/2021 25/03/2021 128078 N N Y
157035 25/03/2021 25/03/2021 128078 N N Y
157036 12/04/2021 12/04/2021 117022 N N Y
157036 12/04/2021 12/04/2021 117034 N N Y
157036 9/04/2021 9/04/2021 128078 N N Y

Но так и должно быть:

bst__ref врз__дат vrzv_dat afg__ref указ____ fac__tst vrz__tst
157035 2/04/2021 2/04/2021 117210 N N Y
157035 2/04/2021 25/03/2021 128078 N N Y
157035 2/04/2021 25/03/2021 128078 N N Y
157036 12/04/2021 12/04/2021 117022 N N Y
157036 12/04/2021 12/04/2021 117034 N N Y
157036 12/04/2021 9/04/2021 128078 N N Y

Как, черт возьми, я могу это сделать, используя только SQL? Спасибо!

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

1. Какую СУБД вы используете?

2. Собственный клиент FireDAC / Phys / ODBC / Microsoft / SQL Server 11.0

3. Что определяет «первый ряд», как вы их упорядочиваете?

4. @Charlieface понятия не имею, но обычно первая строка никогда не будет с afg__ref 128078

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

Ответ №1:

Вам нужно сопоставить данные с той же таблицей. Существуют различные способы достижения этой цели, вы, похоже, хотите сделать это специально для одного значения, поэтому, если я правильно понял, вы можете попробовать это

 update b set 
vrz__tst = 'Y',
fac__tst = 'N',
vrz__dat = 
    case when afg_ref=128078 then 
        (select Min(vrzv_dat) from bstlyn__ b2 where b2.bst_ref=b.bst_ref)
    else vrzv_dat end
from  bstlyn__ b
where fiat____ = 'N' and fac__tst = '0'
 

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

1. Хм, в случае, если вы имели Min(vrzv_dat) в виду, что он выводит то же самое, что и при использовании моего запроса. В случае, если вы имели Min(vrz__dat) в виду, что это не меняет ни одну строку с afg__ref 128078. Он также должен изменить их на те же vrzv_dat из 1 строки, в которой нет afg__ref 128078 (но которые имеют одинаковое bst__ref значение ). Трудно объяснить, не так ли… 🙂

2. Да, возможно, я действительно имел это в виду — tbh Я видел более легко читаемые запросы. Если бы было лучше, например, для примера данных, чтобы вы просто назвали столбец A, B, C и т. Д. 🙂

3. Изменил имена столбцов в верхней таблице, надеюсь, теперь это немного легче понять. Итак, B должен стать тем же значением, что и C, но когда D имеет значение «128078», он должен выполнить поиск в тех же строках A, а затем выбрать дату из первой строки (или строки, в которой нет «128078» в D) из столбца C и обновить ее. Таким образом, все строки из одного столбца A должны иметь одинаковое значение в столбце C

4. Ага! Я думаю, что нашел его; update b set vrz__tst = 'Y', fac__tst = 'N', vrz__dat = case when afg__ref='128078' then (select Max(vrzv_dat) from bstlyn__ b2 where b2.bst__ref=b.bst__ref) else vrzv_dat end from bstlyn__ b where fiat____ = 'N' and fac__tst = '0' Конечно, в этом сценарии дата всегда должна быть выше, но в моем случае использования это (обычно) всегда будет так.

Ответ №2:

Вы можете использовать эту таблицу дважды, вам просто нужно указать псевдоним таблицы в подзапросах. Затем выполните извлечение только первого для каждого такого же кода

попробуйте этот код:

 UPDATE bstlyn__ t, (SELECT DISTINCT A,B,C,D,E,F,G
                    FROM bstlyn__ ) t1
SET t.B = t1.C, G = 'Y', F = 'N'
WHERE t.A= t1.A
 

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

1. Я попробовал UPDATE bstlyn__ SET vrz__tst = 'Y', fac__tst = 'N', vrz__dat = (SELECT vrzv_dat FROM (SELECT TOP 1 vrzv_dat FROM bstlyn__ ORDER BY bst__ref) t) WHERE fiat____ = 'N' AND fac__tst = '0' , но затем он занимает первое место в таблице (с датой 4/05/2012)

2. Некоторое объяснение того, как работает ваш ответ, в значительной степени одобрило бы этот ответ. ОП должен уметь извлекать уроки из этого, а не просто копировать/проходить и радоваться, что это работает.