Обновить или вставить (несколько строк и столбцов) из подзапроса в PostgreSQL

106

Я пытаюсь сделать что-то подобное в postgres:

  • UPDATE table1 SET (col1, col2) = (SELECT col2, col3 FROM othertable WHERE othertable.col1 = 123);

  • INSERT INTO table1 (col1, col2) VALUES (SELECT col1, col2 FROM othertable)

Но пункт 1 невозможен даже с postgres 9.0, как указано в документации ( http://www.postgresql.org/docs/9.0/static/sql-update.html )

Также пункт 2 кажется неработающим. я получаю следующую ошибку: подзапрос должен возвращать только один столбец.

Надеюсь, у кого-то есть обходной путь для меня. в противном случае запросы отнимут уйму времени :(.

К вашему сведению: я пытаюсь выбрать разные столбцы из нескольких таблиц и сохранить их во временной таблице, чтобы другое приложение могло легко получить подготовленные данные.

dforce
источник

Ответы:

175

Для ОБНОВЛЕНИЯ

Использование:

UPDATE table1 
   SET col1 = othertable.col2,
       col2 = othertable.col3 
  FROM othertable 
 WHERE othertable.col1 = 123;

Для INSERT

Использование:

INSERT INTO table1 (col1, col2) 
SELECT col1, col2 
  FROM othertable

Вам не нужен VALUESсинтаксис, если вы используете SELECT для заполнения значений INSERT.

OMG Пони
источник
1
Можно ли объединить обновление и вставку, чтобы в случае сбоя одного из них использовалось другое без выдачи ошибки (независимо для каждой строки). Я думаю, что это было бы более полное решение вопроса (например: stackoverflow.com/a/6527838/781695 )
пользователь
26

Ответ OMG Ponies работает отлично, но на всякий случай, если вам нужно что-то более сложное, вот пример немного более сложного запроса на обновление:

UPDATE table1 
SET col1 = subquery.col2,
    col2 = subquery.col3 
FROM (
    SELECT t2.foo as col1, t3.bar as col2, t3.foobar as col3 
    FROM table2 t2 INNER JOIN table3 t3 ON t2.id = t3.t2_id
    WHERE t2.created_at > '2016-01-01'
) AS subquery
WHERE table1.id = subquery.col1;
Дэвид Намени
источник
1
Ты лучший :) :)
Ашвини
1
идеальный. это лучше всего работает, когда вам нужно выбрать подмножество на основе условия, связанного с самой обновленной таблицей.
мифический
@ Дэвид Намени, ты можешь объяснить этот вопрос?
Чинтан Патхак 08
15
UPDATE table1 SET (col1, col2) = (col2, col3) FROM othertable WHERE othertable.col1 = 123;
Уолтер
источник