Я пытаюсь сделать вставку, где первая строка — это элемент по умолчанию, а остальные строки — это варианты с другим языком (создание первичного ключа с идентификатором и языковым стандартом), и я думал о чем-то вроде этого, но это не работает:
with data as (
select uuid_generate_v4() as uuid
)
insert into content (id, type, locale)
select
(uuid, 'page', 'en-us'),
(uuid, 'page', 'es-mx')
from data
Я попытался использовать CTE, чтобы получить UUID, а затем использовать его для всех вставок, для этого мне нужно использовать SELECT вместо VALUES, мне также нужно вернуть результаты.
Я нашел это решение, но не уверен, можно ли его улучшить:
with data as (
select uuid_generate_v4() as uuid
)
insert into content (id, type, locale)
select data.uuid, 'page', 'en-us'
from data
union
select data.uuid, 'page', 'es-mx'
from data
Таким образом, я могу добавить N раз вариантов для каждого языка, используя один и тот же uuid.
Используйте UNION ALL
вместо UNION
, чтобы повысить производительность, если вы не уверены, что ваш список языков содержит один и тот же язык несколько раз, и вам нужно исключить дубликаты. См. dbfiddle.uk/udas1_rO
@JonasMetzler Я могу фильтровать дубликаты перед созданием sql, при использовании UNION ALL
можно добавить несколько selects from...
, скажем, добавить еще два языка?
Конечно, вы можете объединить многие из них. Я не знаю, есть ли какой-либо лимит на максимальное количество UNION ALL
запросов в PostgreSQL, я никогда не слышал, чтобы кто-то с этим сталкивался. Поэтому я не могу себе представить, что это будет проблемой для вас.
342 раза union all
не кажется проблемой (см.: dbfiddle.uk/bkaHlStm), так что есть много вариантов, прежде чем нажать «может быть, мне следует изменить дизайн своей базы данных... 😉»
Вы можете использовать unnest() для преобразования массива в несколько строк (и string_to_array для разделения строки на массив):
insert into content (id, type, locale)
select uuid_generate_v4(), 'page', unnest(string_to_array('en-us,es-mx',','))
ОП пытался использовать один и тот же UUID для всех строк («... чтобы получить UUID, а затем использовать его для всех вставок...»). Это создает разные uuid.
Вы можете использовать CTE, но с этой задачей справится простой подзапрос. Вы просто не сможете сохранить функцию uuid_generate_v4()
в списке SELECT
, иначе для каждой строки будет генерироваться новый UUID.
INSERT INTO content (id, type, locale)
SELECT id, 'page', locale
FROM uuid_generate_v4() id
, unnest('{en-us, es-mx}'::text[]) locale;
Или даже:
INSERT INTO content (id, type, locale)
SELECT id, 'page', unnest('{en-us, es-mx}'::text[])
FROM uuid_generate_v4() id;
О функциях, возвращающих наборы, в списке SELECT
:
Меня интересует ваш реляционный дизайн, который потребует избыточного хранения «страницы»...
Эта ерунда с UUID вышла из-под контроля. Зачем создавать UUID (универсальный уникальный идентификатор), который вы хотите повторить?