更新 postgres 中的多个案例

Multiple case in update postgres

我需要用相同的条件更新 table 中的 2 列。我知道,他们每个人都会花很多时间。如何将 2 个更新连接成 1 个,这样会更快?

-- 第一次更新

update t1
set col1 =
case when cc1  is not NULL and cc1  <> 0 then 'A'
        when cc2 is not NULL and cc2 <> 0 then 'B'
        when cc3 is not NULL and cc3 <> 0 then 'C'
       else null
end;

-- 条件相同

update t1 
             set    col2 =
             case when cc1  is not NULL and cc1  <> 0 then 'qwe rty'
                     when cc2 is not NULL and cc2 <> 0 then 'qzaz wsx'
                     when cc3 is not NULL and cc3 <> 0 then 'zxcv asdf'
              else 'pl ok'
             end;

-- 我拼接的努力,没用

update  t1
             set    (col1, col2)  =
             (select c1, c2 from
              (select case when t2.cc1  is not NULL and  t2.cc1  <> 0 then 'A' as c1,  'qwe rty' as  c2
                     when t2.cc2 is not NULL and t2.cc2 <> 0 then ('B', 'qaz wsx')
                     when t2.cc3 is not NULL and t2.cc3 <> 0 then ('C', ' zxcv asdf')
              else (null, 'pl ok')
             end 
             from t1 as t2 where t1.key_column1 = t2.key_column1 and t1.key_column2 = t2.key_column2 and t1.key_column3 = t2.key_column3) f)

       ;

这就是我要做的方式。

WITH cte AS (SELECT * FROM 
             (VALUES(1, 'A', 'qwe rty'),(2, 'B', 'qaz wsx'),(3, 'C', 'zxcv asdf'),(4, NULL, 'pl ok')) v (id,c1,c2)) 
UPDATE so_demo
SET col1 = cte.c1, col2 = cte.c2
FROM cte WHERE cte.id = CASE WHEN COALESCE(cc1, 0) <> 0 THEN 1 
                             WHEN COALESCE(cc2, 0) <> 0 THEN 2
                             WHEN COALESCE(cc3, 0) <> 0 THEN 3 
                             ELSE 4 END;

作为解释,我已经将可能的值放入一个 cte 中,除了值之外还为它们分配了一个 id。然后我可以将 case 语句放在生成必要 id 的 where 子句中。请注意使用 COALESCE 使 WHEN 更易于阅读。

一种方法是使用数组。

UPDATE t1 
       SET (col1,
            col2) = (SELECT x[1],
                            x[2]
                            FROM (SELECT CASE
                                           WHEN cc1 IS NOT NULL
                                                AND cc1 <> 0 THEN
                                             ARRAY['A',
                                                   'qwe rty']
                                           WHEN cc2 IS NOT NULL
                                                AND cc2 <> 0 THEN
                                             ARRAY['B',
                                                   'qzaz wsx']
                                           ...
                                           ELSE
                                             ARRAY[NULL,
                                                   'pl ok']
                                         END) AS x
                                                 (x));

但就运行时优化而言,与UPDATE ... SET col1 = CASE ..., col2 = CASE ...相比的增益应该可以忽略不计。