Элегантное решение проблемы увеличения инкремента при вставке дубликатов.
Множество раз в различных форумах всплывает вопрос: Как избежать увеличения автоинкремента при вставке дубликатов в таблицу?
Хотя я сам на тех же форумах отвечал что это не критично и не стоит из-за этого волноваться, а если волнуетесь то используйте bigserial и тогда точно хватит! Но душа тем не менее требовала гармонии. И так классика:
create table tbl ( id serial, val text, primary key (id), unique (val) ); -- Вставляем Раз и Два insert into tbl (val) values ('One'), ('Two'); -- Попробуем так insert into tbl (val) values ('One'), ('Three') on conflict (val) do nothing; select * from tbl; +====+=======+ | id | val | +====+=======+ | 1 | One | | 2 | Two | | 4 | Three | +----+-------+
Видно, автоинкремент растет даже если мы используем UPSERT Конечно есть вариант с проверкой NOT EXISTS, но это не для слабонервных:
insert into target2 (val) select val from source where not exists (select true from target2 where target2.val = source.val);
И вот наконец то в PostgreSQL 15 завозят оператор MERGE:
merge into target3 t using source s on t.val = s.val when not matched then insert (val) values (val);
здесь читаем про Применение оператора MERGE в PostgreSQL
