Итерация над переменной и вставка дополнительных строк Postgres
Просто хочу отметить, да, я видел подобные вопросы здесь, но ни один не был достаточно близким для данного конкретного вопроса.
У меня есть таблица (назовем ее 'table 1') в postgres с тремя колонками, основанными на модели django, 'ID' (автоматически увеличивающееся значение), 'affiliation' и 'entry'.
Мне нужно взять каждую запись, где affiliation = 52, а затем добавить дополнительную строку с entry = query.entry и affiliation = 48 (повторюсь, мне нужны дополнительные строки, а не измененные значения). Мне также нужно убедиться, что пара entry + affiliation еще не существует
Несмотря на то, что я делаю, я получаю синтаксическую ошибку! Есть помощь?
Последний звонок был:
do $$
declare
id_array int[];
begin
insert into id_array table_1.entry where table_1.affiliation = 52;
for id in id_array
loop
if not exists (select entry from table_1 where affiliation = 48)
then
insert into table_1 (affiliation, entry) values (48, id);
else
raise notice "already exists";
end if;
endloop;
end; $$
Есть идеи? Я в полной растерянности... Это, безусловно, самый сложный запрос, который я когда-либо выполнял.
Для этого не нужен (неуклюжий, неэффективный и неправильный) цикл.
Для начала у вас должно быть ограничение UNIQUE
на (affiliation, entry)
.
С UNIQUE
индексом
При наличии UNIQUE
ограничения или индекса на (affiliation, entry)
просто используйте "UPSERT":
INSERT INTO table_1 (affiliation, entry)
SELECT 48, entry
FROM table_1
WHERE affiliation = 52
ON CONFLICT DO NOTHING;
ON CONFLICT DO NOTHING
пропускает любого потенциального дубликата. Работа выполнена.
Это защищает от условий гонки при одновременной нагрузке на запись. См.:
Без UNIQUE
индекса
SELECT DISTINCT 48, t1.entry
FROM table_1 t1
LEFT JOIN table_1 t2 ON t2.entry = t1.entry
AND t2.affiliation = 48
WHERE t1.affiliation = 52
AND t2.entry IS NULL; -- does not exist yet
Я добавил DISTINCT
, так как без указанного индекса UNIQUE
могут быть дубликаты на (affiliation, entry)
для начала, а нам не нужно более одной копии.
Не защищено от условий гонки при одновременной нагрузке записи.
Смотрите:
Оба запроса предполагают, что entry
будет определено NOT NULL
. В противном случае необходимо определить, как работать со значениями NULL
.