La expresión CASE en SQL Server

Problema:

CASE es una de las más potentes y más complejas expresiones incorporadas en Transact-SQL. Debido a su nombre, esta expresión es regularmente confundida con la sentencia CASE disponible en otros lenguajes. En SQL Server, el propósito de la expresión CASE es devolver siempre una expresión. No tiene la intención de efectuar un control de flujo, es por eso que no la llamamos instrucción CASE. A continuación, comparto algunos de los puntos que vemos en NUESTROS CURSOS de cómo utilizar mejor una expresión CASE.

 

Solución:

Hay dos opciones diferentes para la expresión CASE: la expresión CASE «simple», y la expresión CASE de “búsqueda”. La “simple” comienza con una expresión y la compara con cada una de los posibles valores (estos pueden ser expresiones, pero son típicamente constantes o variables):

 

CASE [input_expression]
  WHEN [eval_expression] THEN [output_expression]
  …
  ELSE [output_expression]
END

 

La opción de «busqueda» no se inicia con una expresión de entrada, sino que se sumerge directamente en las comparaciones (estas son expresiones completas que pueden ser evaluadas, y no están restringidos a la igualdad):

 

CASE
  WHEN [full_eval_expression] THEN [output_expression]
  …
  ELSE [output_expression]
END

 

 

Inicia 28 de Noviembre

 

 

Ejemplos:

 

DECLARE @variable int = 5;

SELECT [simple] = CASE @variable
  WHEN 1 THEN ‘One’
  WHEN 5 THEN ‘Five’
  ELSE ‘Some other number’
END;

SELECT [searched] = CASE
  WHEN @variable = 1 THEN ‘One’
  WHEN @variable = 5 THEN ‘Five’
  ELSE ‘Some other number’
END;

 

Desde mi punto de vista, encuentro que la variante de “búsqueda” se utiliza más a menudo, ya que es mucho más flexible. Por ejemplo, si quiero comprobar los valores de dos variables, o utilizar cualquier tipo de comparación que no sea la igualdad, puedo hacer esto:

 

SELECT  CASE   WHEN @a > 5 OR @b <= 10 THEN c + @a – @b    ELSE c – @b + @a END FROM dbo.table;

 

Cortocircuitos

Ya sea que use la opción “simple” o de “búsqueda”, puedo tener varias cláusulas WHEN, de las cuales sólo una expresión se puede evaluar como verdadera. En la mayoría de los casos, se puede confiar en la secuencialidad y devolver la primera evaluación que se evalúa como verdadera.

También es bueno colocar una cláusula ELSE para asegurarnos que nunca falle nuestra consulta.

 

DECLARE @i int = 0;

SELECT CASE
  WHEN @a =  0 THEN  0
  WHEN @a >= 0 THEN +1
  WHEN @a <  0 THEN -1
  ELSE 1/0
END;

 

Inicia 28 de Noviembre

 

Donde se puede utilizar CASE

CASE se puede utilizar en cualquier lugar donde una columna, variable, expresión, o constante se pueda utilizar. Todas esas opciones son válidas, como vemos en el siguiente ejemplo:

 

DECLARE @i int = 1;
SELECT name,
  FirstLetter = MAX(CASE
      WHEN name LIKE N’S%’ THEN ‘Starts with S’
      ELSE ‘Does not start with S’
    END)
  FROM sys.databases
WHERE CASE @i
    WHEN 1 THEN name
    ELSE recovery_model_desc END
  = CASE @i
    WHEN 2 THEN recovery_model_desc
    WHEN 5 THEN name
    ELSE ‘Some constant’
  END
GROUP BY CASE @i WHEN 2 THEN name ELSE REVERSE(name) END
ORDER BY CASE WHEN database_id < 5 THEN database_id END;

 

Consideraciones para la anidación

Las expresiones CASE se pueden anidar:

 

DECLARE @tier int = 2;SELECT
 CASE WHEN @tier > 1 THEN
   CASE WHEN @tier > 2 THEN
     CASE WHEN @tier > 3 THEN
       CASE WHEN @tier > 4 THEN
         CASE WHEN @tier > 5 THEN
           ‘Awesome’
         ELSE ‘Great’ END
       ELSE ‘Good’ END
     ELSE ‘Acceptable’ END
   ELSE ‘Poor’ END
 ELSE ‘Invalid’ END;

 

 

Pero hay que tener cuidado, dado que se  puede convertir en algo complejo rápidamente, especialmente cuando se mezclan tipos de datos, y hay un límite estricto sobre el número de expresiones CASE anidados: 10. Así que la siguiente consulta no es válida:

DECLARE @i int = 1;SELECT
  CASE @i WHEN 1  THEN CASE @i WHEN 2  THEN
  CASE @i WHEN 3  THEN CASE @i WHEN 4  THEN
  CASE @i WHEN 5  THEN CASE @i WHEN 6  THEN
  CASE @i WHEN 7  THEN CASE @i WHEN 8  THEN
  CASE @i WHEN 9  THEN CASE @i WHEN 10 THEN
  CASE @i WHEN 11 THEN ‘Whoopsies’
END END END END END END END END END END END;

 

No daría el siguiente mensaje de error:

 

Msg 125, Level 15, State 3, Line 9
Case expressions may only be nested to level 10.

 

Resumen

La expresión CASE es poderosa, pero tiene algunos matices que a menudo sorprenden a los nuevos usuarios. Si está utilizando expresiones CASE, usted debe familiarizarse con su funcionamiento y, más importante aún, identificar cuando se podrían producir resultados inesperados.

 

Inicia 28 de Noviembre