2012-06-27 16 views
8

È possibile utilizzare un'istruzione CASE all'interno di una clausola IN?Utilizzo dell'istruzione CASE all'interno della clausola IN

Questa è una versione semplificata di quello che ho cercato di ottenere una corretta compilazione:

SELECT * FROM MyTable 
WHERE StatusID IN (
CASE WHEN @StatusID = 99 THEN (5, 11, 13) 
ELSE (@StatusID) END) 

Grazie!

risposta

21

CASE restituisce solo un valore scalare. Puoi farlo invece. (Io parto dal presupposto, secondo il vostro esempio, che quando @StatusID = 99, un valore StatusId di 99 non è una partita.)

select * 
from MyTable 
where (@StatusID = 99 and StatusID in (5, 11, 13)) 
    or (@StatusID <> 99 and StatusID = @StatusID) 
+1

@ LittleBobbyTables Con il tuo nome, sono sicuro che puoi cambiarlo nel back-end :) – RedFilter

+0

Grazie! Ottima soluzione! – crjunk

3

No. Al contrario, si può mettere fuori

SELECT * 
FROM MyTable 
WHERE 1 = (CASE WHEN @StatusID = 99 and StatusId in (5, 11, 13) then 1 
       WHEN coalesce(@StatusId, 0) <> 99 and StatusId in (@StatusID) then 1 
       ELSE 0 
      END) 

Puoi anche scrivere questo senza la dichiarazione del caso.

Un'altra opzione è l'SQL dinamico, in cui si crea effettivamente una stringa con l'istruzione SQL e quindi la si esegue. Tuttavia, SQL dinamico sembra eccessivo in questo caso.

+1

Mi sono chiesto questa sintassi dopo aver letto l'istruzione batch di qualcun altro, e ora so perché viene utilizzata. Ottimo suggerimento, grazie, @ gordon-linoff – Sung

0

Ho pensato di provarlo in modo diverso utilizzando un Table Valuue Constructor - i TVC non sono consentiti nel seguente contesto?

SELECT * 
FROM MyTable 
WHERE StatusID IN 
    ( 
    SELECT 
     CASE 
     WHEN @StatusID = 99 THEN (values(5),(11),(13)) t(StatusID) 
     ELSE @StatusID 
    END 
    ) 
0

È possibile farlo utilizzando TVC, ma l'approccio è leggermente diverso. Non usa caso, ma sarà più a misura d'bene dove ci sono una serie di possibili opzioni tra cui scegliere:

SELECT * 
FROM MyTable 
join (values 
     (99,5),(99,11),(99,13), 
     (@StatusID , @StatusID)  
    ) t(k,v) on t.k= @StatusID and t.v = StatusID) 

o se avete bisogno di tutto nella clausola in cui poi:

SELECT * 
FROM MyTable 
WHERE exists (
    select 1 
    from (values 
     (99,5),(99,11),(99,13), 
     (@StatusID , @StatusID)  
    ) t(k,v) 
    where t.k= @StatusID and t.v = StatusID) 
Problemi correlati