#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
1280785. Если вы не можете определить, как мы получаем первую строку, как мы можем это решить? Помните, что таблицы не имеют внутреннего порядка, результаты могут каждый раз отличаться без явного упорядочения
Ответ №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. Некоторое объяснение того, как работает ваш ответ, в значительной степени одобрило бы этот ответ. ОП должен уметь извлекать уроки из этого, а не просто копировать/проходить и радоваться, что это работает.