Как избавиться от дублирования SELECT-запроса при вставке в таблицу БД PostgreSQL?

Рейтинг: 0Ответов: 2Опубликовано: 17.02.2023

При вставке в таблицу нужно указать id группы, полученного из другой таблицы. Ставку нужно делать только для одной группы пользователей. Записей может быть очень много - миллионы :) Вариант "Посмотреть в БД и жестко указать в запросе" не подходит - на разных стендах могут быть разные id.

Запрос вида:

INSERT INTO accounts(user_id, group_id) VALUES 
('12345678-1234-1234-1234-123456789001', (select g.id from groups g where g.name = 'pilots')),
('12345678-1234-1234-1234-123456789002', (select g.id from groups g where g.name = 'pilots')),
('12345678-1234-1234-1234-123456789003', (select g.id from groups g where g.name = 'pilots')),
('12345678-1234-1234-1234-123456789004', (select g.id from groups g where g.name = 'pilots'));

надо модифицировать так, чтобы не нужно было N раз делать SELECT, а только один раз в самом начале.

В MySQL это выглядело бы так:

SELECT id INTO @groupid FROM groups WHERE name = 'pilots';
INSERT INTO accounts(usere_id, group_id) VALUES
    ('12345678-1234-1234-1234-123456789001', @groupid),
    ('12345678-1234-1234-1234-123456789002', @groupid), 
    ('12345678-1234-1234-1234-123456789003', @groupid);

С PostgeSQL не получается реализовать.

Ответы

▲ 0
INSERT INTO accounts(user_id, group_id)
select x.user_id, g.id
  from groups g
 cross join (values
     ('12345678-1234-1234-1234-123456789001'),
     ('12345678-1234-1234-1234-123456789002'),
     ...
 ) as x(user_id)
 where g.name = 'pilots'
▲ 0

Предложу еще один ответ, чуть-чуть отличающийся от варианта, предложенного @Mike

INSERT INTO accounts(user_id, group_id) 
select user_id,(select g.id from groups g where g.name = 'pilots') group_id 
from (VALUES 
('12345678-1234-1234-1234-123456789001'),
('12345678-1234-1234-1234-123456789002'),
('12345678-1234-1234-1234-123456789003'),
('12345678-1234-1234-1234-123456789004')
)t(user_id);

Однако, есть сомнения в пояснении к задаче. Представляется, что прямая вставка с большой группы записей с использованием VALUES(x1),...(xn) вряд ли применяется на практике. Скорее всего, это будет выборка из другой таблицы и затем вставка в целевую. Примерно так:

INSERT INTO accounts(user_id, group_id) 
select user_id,(select g.id from groups g where g.name = 'pilots') group_id 
from RawData r
where r.groupName='pilots'

Т.е. применится операция INSERT INTO ... FROM