1

I am trying to write a case statement inside the IN clause.

The Channel column contains three values ACT, REN, REP. I want to select more than 1 values, but I get result with only one value.

    select * from tbl
    WHERE tbl.Channel IN (select 
                                    case when @ACT =1 then 'ACT'
                                    when @REN =1 then 'REN' 
                                    when @REP =1 then 'REP' END)

What changes should I be doing here ?

user1989
  • 217
  • 2
  • 13
  • Possible duplicate: http://stackoverflow.com/questions/1904314/only-one-expression-can-be-specified-in-the-select-list-when-the-subquery-is-not – Kris Gruttemeyer Nov 04 '14 at 21:40
  • Are you using MySQL or SQL Server? Please only tag with the platform you are actually using. Those tags have descriptions when you mouse over them; please read them before using them. – Aaron Bertrand Nov 04 '14 at 21:54
  • @AaronBertrand I see that a lot recently. Probably due to this http://meta.stackoverflow.com/questions/275170/stop-generic-database-questions-from-getting-mysql-as-a-suggested-tag – Martin Smith Nov 04 '14 at 22:04
  • 1
    @Martin Could be. Also see http://meta.stackexchange.com/questions/207274/suggested-tags-both-sql-server-and-mysql-are-suggested-by-the-system and the discussion under Shog's answer [here](http://meta.stackoverflow.com/questions/274632/help-the-helpless-with-how-to-ask-tag-tips). – Aaron Bertrand Nov 04 '14 at 22:09
  • @AaronBertrand hopefully they extend the new tag tips feature to be a bit more intelligent and recognise specific RDBMS platforms so it doesn't warn you when it is already tagged. Then I guess it will be a short step to recognise you have multiple tagged. – Martin Smith Nov 04 '14 at 22:12
  • @Martin Yeah, I do sense that it is getting worse and not better. – Aaron Bertrand Nov 04 '14 at 22:18

4 Answers4

4

Don't end your case. You are returning 3 columns. You only want one.

select * from tbl
    WHERE tbl.Channel =  case when @ACT =1 then 'ACT' 
                              when @REN =1 then 'REN'
                              when @REP =1 then 'REP' 
                              else NULL END
Bill Gregg
  • 7,067
  • 2
  • 22
  • 39
3

This will work fine. SQL Fiddle

The only change is removing the select so the input to the in clause is 3 values rather than a single row with three columns.

The implicit else null if the variable is not 1 does not cause a problem in an in clause.

SELECT * 
FROM   tbl 
WHERE  tbl.channel IN ( CASE 
                          WHEN @ACT = 1 THEN 'ACT' 
                        END, CASE 
                          WHEN @REN = 1 THEN 'REN' 
                        END, CASE 
                               WHEN @REP = 1 THEN 'REP' 
                             END ) 
Martin Smith
  • 438,706
  • 87
  • 741
  • 845
1

You can write the clause without a case at all:

select *
from tbl
where (tbl.Channel 'ACT' and @ACT = 1) or
      (tbl.Channel = 'REN' and @REN = 1) or
      (tble.Channel = 'REP' and @REP = 1);

Your select statement is not correct and should return an error. select statements in in clauses are not allowed to return more than one column.

Gordon Linoff
  • 1,242,037
  • 58
  • 646
  • 786
1

Here is an alternative that should let you perform the selection without an IN operator:

select * from tbl
WHERE (tbl.Channel='ACT' AND @ACT=1)
   OR (tbl.Channel='REN' AND @REN=1)
   OR (tbl.Channel='REP' AND @REP=-1)

If you must use IN operator, you should be able to construct a query with UNION ALL, like this:

select * from tbl
WHERE tbl.Channel IN (
    select case when @ACT =1 then 'ACT' END FROM DUAL
        UNION ALL
    select case when @REN =1 then 'REN' END FROM DUAL
        UNION ALL
    select case when @REP =1 then 'REP' END FROM DUAL)

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523