2

I have a select statement which resembles something like this

SELECT
    CASE WHEN <SOME-CONDN_1> THEN 'value1' ELSE '' ||
    CASE WHEN <SOME-CONDN_2> THEN 'value2' ELSE '' ||
    CASE WHEN <SOME-CONDN_3> THEN 'value3' ELSE '' AS value_column,
    CASE WHEN <SOME-CONDN_1> THEN 'name1' ELSE '' ||
    CASE WHEN <SOME-CONDN_2> THEN 'name2' ELSE '' ||
    CASE WHEN <SOME-CONDN_3> THEN 'name3' ELSE '' AS name_column
FROM data_table
--<REST OF THE QUERY>

The conditional statement is something like data_table.data_column ILIKE value1 and so on. Since I'm doing the same conditioning statement twice (and it involves some string matching using ILIKE) I was wondering if I could club them and make it more efficient.

Would the same be possible using SQL statements?

3
  • 2
    This tends to quickly become vendor specific in terms of syntax - what vendor are you asking about? Commented Oct 13, 2014 at 15:09
  • I am using Redshift Database. It mostly uses PostGreSQL. Commented Oct 13, 2014 at 15:13
  • Redshift is an analytical DB with the ability to optimize queries across billion of records. Storing textual data and doing string manipulation is not the best practice. Please consider using some preprocessing that will parse your data and put it to the right columns instead of the above complex and slow query. Commented Oct 15, 2014 at 11:27

2 Answers 2

1

Option 1: not quite sure if this variant of CASE works for PostgreSQL...

select case cond_num when 
    1 then 'value1'
    when 2 then 'value2',
    when 3 then 'value3' else null end as value_column,
case cond_num when 
    1 then 'name1'
    when 2 then 'name2',
    when 3 then 'name3' else null end as name_column
from (
select data_table.*,
    case when <some_condition_1> then 1 
    when <some_condition_2> then 2
    when <some_condition_3> then 3 else 0 end as cond_num
from data_table
) screened_table
;

Option 2:

select case when 
    cond1 = 1 then 'value1'
    when cond2 = 1 then 'value2',
    when cond3 = 1 then 'value3' else null end as value_column,
case when 
    cond1 = 1 then 'name1'
    when cond2 = 1 then 'name2',
    when cond3 = 1 then 'name3' else null end as name_column
from (
select data_table.*,
    case when <some_condition_1> then 1 else 0 as cond1,
    case when <some_condition_2> then 1 else 0 as cond2,
    case when <some_condition_3> then 1 else 0 as cond3
from data_table
) screened_table
;

Option 3 - note if the conditions are not exclusive may return multiple rows. Will not return rows from data_table in which no conditions are true.

select rslt.name, rslt.value
from data_table, (
    select 1 as cond, 'value1' as value, 'name1' as name
    union all
    select 2 as cond, 'value2' as value, 'name2' as name
    union all
    select 3 as cond, 'value3' as value, 'name3' as name
) rslt
WHERE (<some_condition_1> and rslt.cond = 1) OR
    (<some_condition_2> and rslt.cond = 2) OR
    (<some_condition_3> and rslt.cond = 3)

;

Sign up to request clarification or add additional context in comments.

Comments

0

Assuming the results are both strings you can use an array to make things simpler.

SELECT a[1],a[2], ...
FROM (SELECT CASE 
        WHEN <SOME-CONDN_1> THEN ARRAY['value1','name1'] 
        WHEN <SOME-CONDN_2> THEN ARRAY['value2','name2'] 
        WHEN <SOME-CONDN_3> THEN ARRAY['value3','name3'] 
        ELSE '' AS a
    FROM ...
);

If the result values are not all the same type you can do the same thing using a ROW() constructor, but you will need to define a type in order to get the values individually "back out of the row".

1 Comment

unfortunately redshift does not support arrays. Otherwise this was the perfect solution. docs.aws.amazon.com/redshift/latest/dg/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.