0

UPDATE с использованием WITH и CASE - PostgreSQL

13

Вопрос для 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 ответ(ов)

0

Ошибка синтаксиса возникает из-за того, что ваш связанный подзапрос недействителен. У вас отсутствует оператор 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

Таким образом, обновление происходит более лаконично, без необходимости в дополнительных подзапросах.

0

Вы можете решить эту задачу с помощью конструкции 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, то используется только имя и фамилия политика, иначе добавляется информация о его офисе.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь