Solved

SQL server conditional case statement in where clause using IN clause

Posted on 2014-07-23
6
985 Views
Last Modified: 2014-07-25
Hi,
I have a situation where I need to filter based on a variable that is being set on a webpage, and if the variable isn't set, then I have to filter based on a comma-delimited string to see if there's a match.
Here it is:
First, I build the comma delimited string, with a STUFF in the FROM clause of the select statement - as follows:
 outer apply
 (
 select
  STUFF
  (
   (    
    select distinct
     ', ' + dx.class
FROM
data_RECORDS sr
 Join data_Xref dx ON sr.Text = dx.text
WHERE sr.userid = @vUID
    order by
     ', ' + dx.class
    for xml path ('')
   ),
   1,
   2,
   ''
  )
 ) mg (Classes)

mg.Classes now contains a long string, comma delimited, of the various classes for this particular user (@Vuid)

Now I want to add an additional condition to the WHERE clause I want to do the filtering.
If a variable with a class name was selected on the input screen, I only want to include that particular class.
If the variable from the input screen is NULL or '', then I want to include all classes from mg.Classes, and I want to filter out the classes that are not part of that string.
I tried many things in the WHERE clause, and they aren't working.
Even though the value of string is correct (it's a comma-delimited string of classes), the WHERE clause does not like the "IN" and is returning an error (Incorrect syntax near the keyword 'CASE'.)

How can I filter to see if the class in the table is in the list of allowed classes that was returned by the STUFF.

Here's a sample:
 WHERE dx.CLASS IN
       (      CASE
      
             when @vClass is NULL
                  then '(' + mg.Classes + ')'
            when @vClass = '' then '(' + mg.Classes + ')'
ELSE @vClass  END )
            
This is complicated, but any help would be GREATLY appreciated!
0
Comment
Question by:avivap
  • 2
  • 2
  • 2
6 Comments
 
LVL 48

Accepted Solution

by:
PortletPaul earned 500 total points
ID: 40216114
If you are you generating the query through something like C#/PHP or similar then using comma separated strings can work - but you need to supply more of the script generating that sql.

as it looks right now you won't get valid sql syntax from that case expression.

---
Despite the fact that A comma separated string looks like an IN() statement, it isn't. It is still ONE string.

if mg.Classes looks: just,like,this,separated,series

when actually being assessed it is treated as a 'single value'

WHERE dx.CLASS IN( 'just,like,this,separated,series' )

and 'just' or 'like' or 'this' or 'separated' or 'series' will not match to any part of  'just,like,this,separated,series'

Could you not use something like this?
 WHERE 
        ( 
         (@vClass is NULL OR @vClass = '') AND dx.CLASS  IN ( 
                                                    select dx.class FROM data_RECORDS sr
                                                    Join data_Xref dx ON sr.Text = dx.text 
                                                    WHERE sr.userid = @vUID         
                                                 ) 
         )
OR 
        ( 
         (@vClass is NOT NULL OR @vClass <> '') AND dx.CLASS = @vClass
         )

Open in new window

0
 
LVL 33

Expert Comment

by:ste5an
ID: 40216171
Think relational and atomic. Thus don't look in the resulting string, but in the raw data. Otherwise you may use an approach like
WHERE   ( COALESCE(@vClass, '') != ''
          AND mg.Classes LIKE '%' + dx.CLASS + '%'
        )
        OR ( COALESCE(@vClass, '') = ''
             AND @vClass = dx.CLASS
           )

Open in new window


But this requires a sligthly different class string. But this leads to the question, why concatenating the values first and searching the result and not in the raw data?
0
 

Author Comment

by:avivap
ID: 40218184
HI.
Thanks for your quick response!
Portletpaul - I tried your solution - and it works.  The only issue is that it takes a lot longer to run, I'm imagining it's because of the additional select in the WHERE clause.  Any ideas regarding optimizing?

Ste5an - I haven't tried yours because you wrote 'But this requires a slightly different class string' - would you mind explaining further?

I'm waiting to hear back from both of you.
Thanks.
0
Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

 
LVL 48

Expert Comment

by:PortletPaul
ID: 40218274
consider indexing these:

dx.class
sr.Text
dx.text
sr.userid  

and in general that statistics are kept up to date and that  indexes are maintained

You can try 'select distinct' in that small subquery it might help (or it might not) I cannot be certian
0
 
LVL 33

Expert Comment

by:ste5an
ID: 40218729
The condition mg.Classes LIKE '%' + dx.CLASS + '%' works only when your class names are not reused as partial name. E.g. the classes Red and CadmiumRed. In the case of the class Red we could get an condition like 'CadmiumRed LIKE '%Red%', which is a false positive. This could be avoided by using ',' + mg.Classes + ',' LIKE '%,' + dx.CLASS + ',%', as concrete expression ',CadmiumRed,' LIKE '%,Red,%'. Now it works under the constraint that no comma is allowed in the content of the atomic class values.
0
 

Author Closing Comment

by:avivap
ID: 40220435
Thank you both for your help!
0

Featured Post

Free Tool: Postgres Monitoring System

A PHP and Perl based system to collect and display usage statistics from PostgreSQL databases.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Why is this different from all of the other step by step guides?  Because I make a living as a DBA and not as a writer and I lived through this experience. Defining the name: When I talk to people they say different names on this subject stuff l…
The Delta outage: 650 cancelled flights, more than 1200 delayed flights, thousands of frustrated customers, tens of millions of dollars in damages – plus untold reputational damage to one of the world’s most trusted airlines. All due to a catastroph…
This video shows, step by step, how to configure Oracle Heterogeneous Services via the Generic Gateway Agent in order to make a connection from an Oracle session and access a remote SQL Server database table.
Via a live example combined with referencing Books Online, show some of the information that can be extracted from the Catalog Views in SQL Server.

830 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question