web-dev-qa-db-fra.com

UPDATE avec WITH et CASE - PostgreSQL

J'essaie de changer les valeurs d'une colonne pour qu'il s'agisse d'un titre construit à partir d'informations provenant de deux autres tables. Toutefois, je ne parviens pas à obtenir les données. Je souhaite actuellement exécuter cette requête sur toutes les entrées de la table. Je reçois une erreur de syntaxe sur CASE et je ne comprends pas pourquoi.

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
    )

C'est PostGres 9.4. Voici l'erreur que je reçois

ERROR:  syntax error at or near "case"
LINE 5:   case
          ^

********** Error **********

ERROR: syntax error at or near "case"
SQL state: 42601
Character: 189
14
cfatt10

L'erreur de syntaxe se produit car votre sous-requête associée n'est pas valide. Vous devez avoir une instruction select après les deux expressions de table courantes: 

La structure de base d'une expression de table commune est la suivante: 

with ptn as (...),
  rc as (...)
select --<< you are missing this select here

Mais je pense que le tout peut être écrit plus court et plus efficacement (si je ne me trompe pas)

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
18

Je serais enclin à le faire avec la clause from:

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
Gordon Linoff