2012-06-27 20 views
8

¿Es posible utilizar una instrucción CASE dentro de una cláusula IN?Uso de la instrucción CASE dentro de la cláusula IN

Ésta es una versión simplificada de lo que he estado tratando de conseguir para compilar correctamente:

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

Gracias!

Respuesta

21

CASE devuelve un valor escalar solamente. Puedes hacer esto en su lugar. (Estoy asumiendo, como por su ejemplo, que cuando @StatusID = 99, un valor de StatusID 99 no es una coincidencia.)

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

@ LittleBobbyTables Con tu nombre, estoy seguro de que puedes cambiar eso en el back-end :) – RedFilter

+0

¡Gracias! ¡Gran solución! – crjunk

3

No. Por el contrario, se puede poner fuera de

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) 

También puede escribir esto sin la declaración del caso.

Otra opción es SQL dinámico, donde realmente se crea una cadena con la instrucción SQL y luego se ejecuta. Sin embargo, el SQL dinámico parece excesivo en este caso.

+1

Me he estado preguntando acerca de esta sintaxis después de leer la declaración de lotes de otra persona, y ahora sé por qué se usa. Un gran consejo, gracias, @ gordon-linoff – Sung

0

Pensé en intentarlo de otra manera utilizando un Constructor de tabla Valuue: ¿no se permiten TVC en el siguiente contexto?

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

Puede hacerlo utilizando TVCs, pero el enfoque es un poco diferente. No utiliza caso, pero va a escalar más bien, donde hay una serie de posibles opciones para elegir:

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 si necesita todo en la cláusula where a continuación:

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) 
Cuestiones relacionadas