#sql #postgresql #sql-insert
Вопрос:
У меня есть несколько (> 100) INSERT
операторов PostgreSQL>, которые все похожи на этот, но с разными вариантами выбора:
INSERT INTO schema.table (geom, name, label, flag, type)
SELECT (geom, <complicated string concatenation from multiple fields>, the_label, TRUE, type_id)
FROM abc.xzy a WHERE a.changelog = 1
ORDER BY a.num;
SQL-запрос может измениться, но его вывод, конечно, выполняется в соответствии с INSERT
требованиями.
Я бы хотел сделать все это с помощью одного INSERT
. Возможно, используя предложение VALUES, например:
INSERT INTO ... VALUES
(val1,val2,val3,val4,...)
, (val11,val12,val13,val14,...)
Показано, что это работает здесь с простыми «статическими» значениями (не из SELECT
операторов).
Но это не работает с SELECT
тем, чтобы получить значения для INSERT
:
INSERT INTO schema.table (geom, name, label, flag, type)
VALUES
(
SELECT (geom, <complicated string concatenation from multiple fields>, the_label, TRUE, type_id)
FROM abc.xzy a WHERE a.changelog = 1
ORDER BY a.num
),
(
SELECT (geom, <complicated string concatenation from multiple fields>, a_label, FALSE, type_id)
FROM def.uvt a WHERE a.typedf
ORDER BY a.idx
),
...
);
Я получаю ошибку: subquery must return only one column
в самой первой открывающей скобке, как раз перед самой первой SELECT
.
Как я мог бы это исправить, если бы это было возможно?
Версия PG >= 9.6.
Ответ №1:
Попытка указывает на путаницу между значениями (полями) и строками (записями).
Тебе не нужно VALUES
выражение лица. Просто используйте SELECT
утверждения напрямую. Цепочка, кратная SELECT
с UNION ALL
:
INSERT INTO schema.table (geom, name, label, flag, type)
(
SELECT geom, <complicated string concatenation from multiple fields>, the_label, TRUE, type_id
FROM abc.xzy a WHERE a.changelog = 1
ORDER BY a.num
)
UNION ALL
(
SELECT geom, <complicated string concatenation from multiple fields>, a_label, FALSE, type_id
FROM def.uvt a WHERE a.typedf
ORDER BY a.idx
);
Дополнительные скобки необходимы только для того, чтобы разрешить ORDER BY
per SELECT
. Но это полезно только в том случае, если важен физический порядок строк. (Для оптимизации производительности.) Порядок вставленных строк не имеет другого значения и может измениться позже с помощью операций записи. Так что вы, вероятно, просто хотите:
INSERT INTO schema.table (geom, name, label, flag, type)
SELECT geom, <complicated string concatenation from multiple fields>, the_label, TRUE, type_id
FROM abc.xzy a WHERE a.changelog = 1
UNION ALL
SELECT geom, <complicated string concatenation from multiple fields>, a_label, FALSE, type_id
FROM def.uvt a WHERE a.typedf;