Как избавиться от дублирования SELECT-запроса при вставке в таблицу БД PostgreSQL?
При вставке в таблицу нужно указать 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 не получается реализовать.
Ответы (2 шт):
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'
Предложу еще один ответ, чуть-чуть отличающийся от варианта, предложенного @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