example - SQL Server 2008-Sentencias Case/If en la cláusula SELECT
select if sql server (6)
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo realizo un IF ... LUEGO en un SQL SELECT? 25 respuestas
Tengo una consulta que se supone que se ejecuta de esta manera:
If(var = xyz) SELECT col1, col2 ELSE IF(var = zyx) SELECT col2, col3 ELSE SELECT col7,col8 FROM . . .
¿Cómo puedo lograr esto en T-SQL sin escribir consultas separadas para cada cláusula? Actualmente lo estoy ejecutando como
IF (var = xyz) { Query1 } ELSE IF (var = zyx) { Query2 } ELSE { Query3 }
Eso es solo una gran cantidad de código redundante para seleccionar diferentes columnas dependiendo de un valor. ¿Alguna alternativa?
CASE es la respuesta, pero deberá tener una declaración de caso por separado para cada columna que desee que se devuelva. Mientras la cláusula WHERE sea la misma, no habrá mucho beneficio separándola en múltiples consultas.
Ejemplo:
SELECT
CASE @var
WHEN ''xyz'' THEN col1
WHEN ''zyx'' THEN col2
ELSE col7
END,
CASE @var
WHEN ''xyz'' THEN col2
WHEN ''zyx'' THEN col3
ELSE col8
END
FROM Table
...
Expresión CASE simple:
CASE input_expression
WHEN when_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
Expresión de CASO buscado:
CASE
WHEN Boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression ]
END
Referencia: http://msdn.microsoft.com/en-us/library/ms181765.aspx
Intenta algo como
SELECT
CASE var
WHEN xyz THEN col1
WHEN zyx THEN col2
ELSE col7
END AS col1,
...
En otras palabras, use una expresión condicional para seleccionar el valor, luego cambie el nombre de la columna.
Alternativamente, podría crear algún tipo de hackeo dinámico de SQL para compartir la cola de consulta; He hecho esto con iBatis antes.
Las soluciones más obvias ya están listadas. Dependiendo de dónde se encuentre la consulta (es decir, en el código de la aplicación), no siempre se pueden usar declaraciones IF y las instrucciones CASE en línea pueden resultar dolorosas cuando muchas columnas se vuelven condicionales. Suponiendo que Col1 + Col3 + Col7 sean del mismo tipo, e igualmente Col2, Col4 + Col8 puedes hacer esto:
SELECT Col1, Col2 FROM tbl WHERE @Var LIKE ''xyz''
UNION ALL
SELECT Col3, Col4 FROM tbl WHERE @Var LIKE ''zyx''
UNION ALL
SELECT Col7, Col8 FROM tbl WHERE @Var NOT LIKE ''xyz'' AND @Var NOT LIKE ''zyx''
Como este es un comando único, hay varias ventajas de rendimiento con respecto al almacenamiento en caché del plan. Además, el Optimizador de consultas eliminará rápidamente aquellas declaraciones donde @Var no coincida con el valor adecuado sin tocar el motor de almacenamiento.
Solo tenga en cuenta que quizás sea mejor que tenga 3 SELECTS separados por razones de optimización. Si tiene un solo SELECT, el plan generado tendrá que proyectar todas las columnas col1, col2, col3, col7, col8, etc., aunque, dependiendo del valor del tiempo de ejecución @var, solo se necesitan algunas. Esto puede resultar en planes que hacen búsquedas de índice agrupadas innecesarias porque el índice no agrupado no cubre todas las columnas proyectadas por SELECT.
Por otro lado, con 3 SELECTS separados, cada una de las columnas necesarias que se proyectan solo puede beneficiarse de índices no agrupados que cubren solo su columna proyectada en cada caso.
Por supuesto, esto depende del esquema real de su modelo de datos y las consultas exactas, pero esto es solo una advertencia para que no traiga el marco mental de pensamiento imperativo de la programación de procedimientos al mundo declarativo de SQL.
Usted está buscando la declaración de caso
http://msdn.microsoft.com/en-us/library/ms181765.aspx
Ejemplo copiado de MSDN:
USE AdventureWorks;
GO
SELECT ProductNumber, Category =
CASE ProductLine
WHEN ''R'' THEN ''Road''
WHEN ''M'' THEN ''Mountain''
WHEN ''T'' THEN ''Touring''
WHEN ''S'' THEN ''Other sale items''
ELSE ''Not for sale''
END,
Name
FROM Production.Product
ORDER BY ProductNumber;
GO