UPDATE с использованием WITH и CASE - PostgreSQL
Вопрос для StackOverflow: Ошибка синтаксиса при использовании CASE в запросе UPDATE в PostgreSQL
Я пытаюсь изменить значения в колонке, чтобы они представляли собой заголовок, составленный из информации из двух других таблиц. Однако у меня возникают трудности с тем, чтобы правильно получить данные. В данный момент я хочу выполнить этот запрос для всех записей в таблице. Я получаю ошибку синтаксиса на конструкции CASE и не могу понять, в чем проблема.
Вот мой запрос:
UPDATE campaigns AS cmp
SET name = (
WITH ptn AS (SELECT first_name, last_name FROM politicians WHERE id = cmp.politician_id),
rc AS (SELECT office FROM races WHERE id = cmp.race_id)
CASE
WHEN rc.office IS NULL OR rc.office = '' THEN ptn.first_name || ' ' || ptn.last_name
ELSE ptn.first_name || ' ' || ptn.last_name || ' for ' || rc.office
END
)
Это PostgreSQL версии 9.4. Вот ошибка, которую я получаю:
ERROR: syntax error at or near "case"
LINE 5: case
^
********** Error **********
ERROR: syntax error at or near "case"
SQL state: 42601
Character: 189
Буду признателен за помощь в решении этой проблемы!
2 ответ(ов)
Ошибка синтаксиса возникает из-за того, что ваш связанный подзапрос недействителен. У вас отсутствует оператор select
после двух общих табличных выражений.
Основная структура общего табличного выражения выглядит так:
with ptn as (...),
rc as (...)
select --<< здесь отсутствует select
Но, на мой взгляд, всё это можно записать короче и эффективнее (если я не ошибаюсь):
UPDATE campaigns AS cmp
SET name = CASE
WHEN rc.office IS NULL OR rc.office = '' THEN ptn.first_name || ' ' || ptn.last_name
ELSE ptn.first_name || ' ' || ptn.last_name || ' for ' || rc.office
END
FROM politicians ptn, races rc
WHERE ptn.id = cmp.politician_id
AND rc.id = cmp.race_id
Таким образом, обновление происходит более лаконично, без необходимости в дополнительных подзапросах.
Вы можете решить эту задачу с помощью конструкции FROM
. Пример SQL-запроса будет выглядеть следующим образом:
UPDATE campaigns AS cmp
SET name = (CASE WHEN rc.office IS NULL OR rc.office = ''
THEN ptn.first_name || ' ' || ptn.last_name
ELSE ptn.first_name || ' ' || ptn.last_name || ' for ' || rc.office
END)
FROM politicians ptn, races rc
WHERE ptn.id = cmp.politician_id AND rc.id = cmp.race_id;
Этот запрос обновляет поле name
в таблице campaigns
с использованием данных из таблиц politicians
и races
. В зависимости от значения office
, формируется нужная строка. Если office
пустое или равно NULL
, то используется только имя и фамилия политика, иначе добавляется информация о его офисе.
Сохранение вывода PL/pgSQL из PostgreSQL в CSV файл
Postgres: Как повысить пользователя до суперпользователя?
Вставка текста с одинарными кавычками в PostgreSQL
Подзапрос внутри вставки (INSERT)
Как объединить все массивы целых чисел из всех записей в один массив в PostgreSQL