Home > Software design >  Multiple case in update postgres
Multiple case in update postgres

Time:01-10

I need to update 2 columns in table with same conditions. I know, that each of them would take a lot of time. How can I concatenate 2 updates into 1, which can be faster?

-- first update

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;

-- with same cond

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;

-- my effort to concatenate, dont work

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)

       ;

CodePudding user response:

This is the way I would do it.

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;

By way of explanation, I have put the possible values into a cte assigning them an id in addition to the values. I can then put the case statement in the where clause generating the necessary id. Note the use of COALESCE to make the WHENs simpler to read.

CodePudding user response:

One way is to use arrays.

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));

But in terms of runtime optimization the gain compared to just UPDATE ... SET col1 = CASE ..., col2 = CASE ... should be neglectable, if any.

  •  Tags:  
  • Related