Home > Back-end >  sql Case condition for multiple columns
sql Case condition for multiple columns

Time:02-27

I have created a query to get below columns as output

SELECT person_number,
       second_year_ltp,
       second_year_salary,
       one_year_bonus,
       one_year_salary,
       one_year_ltp,
       third_year_bonus,
       three_year_ltp,
       three_year_salary,
       current_ltp,
       current_salary,
       current_bonus,
       current_year,
       previous_year,
       second_year,
       third_year,
       fourth_year
FROM   comp_sal 
                     
                 

I want to change values of multiple columns if the sysdate >= '01-04-2022', I cannot write the below code as it will give an error -

select person_number,
 CASE
              WHEN to_char(sysdate,'dd-mm-yyyy') >= '01-04-2022'
              THEN
                    current_bonus        one_year_bonus,
                     current_ltip       one_year_ltp,
                     current_salary     one_year_salary,
                     one_year_bonus     second_year_bonus,
                     one_year_ltp     second_year_ltp,
                     one_year_salary    second_year_salary,
                     second_year_bonus  third_year_bonus,
                     second_year_ltp   three_year_ltp,
                     second_year_salary three_year_salary
                     
                     else 
                     second_year_ltp,
                     second_year_salary,
                     one_year_bonus,
                     one_year_salary,
                     one_year_ltp,
                     third_year_bonus,
                     three_year_ltp,
                     three_year_salary,
                     current_ltip,
                     current_salary
                     end 
                     from comp_sal 
                     

Will I have to write the case when for each column ? is there a better way to do it ?

CodePudding user response:

You need to write one case statement per column.

select person_number,
 (CASE WHEN to_char(sysdate,'dd-mm-yyyy') >= '01-04-2022' THEN current_ltip       ELSE second_year_ltp END) one_year_bonus,
 (CASE WHEN to_char(sysdate,'dd-mm-yyyy') >= '01-04-2022' THEN current_salary       ELSE second_year_salary END) one_year_ltp,
 (CASE WHEN to_char(sysdate,'dd-mm-yyyy') >= '01-04-2022' THEN one_year_salary       ELSE one_year_bonus END) one_year_salary
from comp_sal 

Or you can write two query then combine both with union all. Number of columns in both query should match in appropriate order.

SELECT               person_number,
                     current_bonus        one_year_bonus,
                     current_ltip       one_year_ltp,
                     current_salary     one_year_salary,
                     one_year_bonus     second_year_bonus,
                     one_year_ltp     second_year_ltp,
                     one_year_salary    second_year_salary,
                     second_year_bonus  third_year_bonus,
                     second_year_ltp   three_year_ltp,
                     second_year_salary three_year_salary
                     
from comp_sal where to_char(sysdate,'dd-mm-yyyy') >= '01-04-2022'
union all
select               person_number,                     
                     second_year_ltp,
                     second_year_salary,
                     one_year_bonus,
                     one_year_salary,
                     one_year_ltp,
                     third_year_bonus,
                     three_year_ltp,
                     three_year_salary,
                     current_ltip                                        
from comp_sal where to_char(sysdate,'dd-mm-yyyy') < '01-04-2022'

CodePudding user response:

Yes, you have write a separate case expression for each column. Alternatively, you can write two separate SQL statements, one with your condition in the where clause, and the other has the inverse of it, and combine the two queries using union all

CodePudding user response:

If it is oracle, As an alternative, you can write this as pl/sql block as follows:

declare
v_query varchar2(4000);
begin
 if to_char(sysdate,'dd-mm-yyyy') >= '01-04-2022' then
-- select one set of columns
v_query := 'SELECT person_number,
                     current_bonus        one_year_bonus,
                     current_ltip       one_year_ltp,
                     current_salary     one_year_salary,
                     one_year_bonus     second_year_bonus,
                     one_year_ltp     second_year_ltp,
                     one_year_salary    second_year_salary,
                     second_year_bonus  third_year_bonus,
                     second_year_ltp   three_year_ltp,
                     second_year_salary three_year_salary ';
else
-- select another set of columns
v_query := 'SELECT person_number, second_year_ltp,
                     second_year_salary,
                     one_year_bonus,
                     one_year_salary,
                     one_year_ltp,
                     third_year_bonus,
                     three_year_ltp,
                     three_year_salary,
                     current_ltip,
                     current_salary ';
end if;
 -- CONCAT FROM CLAUSE IN THE QUERY
v_auery := v_query ||' FROM comp_sal ';

-- run the query and store the result set in a table
execute immediate 'CREATE TABLE result_set as '||v_query;

-- your final result will be in the table result_set
end;
  • Related