使用WITH和CASE更新 - PostgreSQL

cfa*_*t10 22 sql postgresql

我正在尝试将列的值更改为从其他两个表中的info构造的标题,但是我在运行数据时遇到了麻烦.我当前想要对表的所有条目执行此查询.我在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
    )
Run Code Online (Sandbox Code Playgroud)

这是PostGres 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
Run Code Online (Sandbox Code Playgroud)

a_h*_*ame 31

发生语法错误是因为您的共同相关子查询无效.您需要select在两个公用表表达式之后有一些语句:

公用表表达式的基本结构如下:

with ptn as (...),
  rc as (...)
select --<< you are missing this select here
Run Code Online (Sandbox Code Playgroud)

但我认为整个事情可以写得更短更有效(如果我没有记错的话)

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
Run Code Online (Sandbox Code Playgroud)


Gor*_*off 11

我倾向于用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 ;
Run Code Online (Sandbox Code Playgroud)