
Estructura Case comparada con Join
La estructura Case evalua una expresión condicional y retorna uno de múltiples resultados.
La estructura Case tiene dos formas (Ver Case en SQL Server)
- La expresión CASE simple compara una expresión con un conjunto de expresiones simples para determinar el resultado.
CASE ExpresiónAEvaluar
WHEN Resultado1 THEN Retorno1 [ …n ]
[ ELSE Expresión ]
END - La expresión CASE buscada evalúa un conjunto de expresiones booleanas para determinar el resultado.
CASE
WHEN ExpresiónCondicional THEN Resultado1 [ …n ]
[ ELSE Expresión ]
END
Ambos formatos admiten un argumento ELSE opcional.
Importante:
CASE se puede usar en cualquier declaración o cláusula que permita una expresión válida.
La estructura CASE se puede usar en SELECT, UPDATE, DELETE y SET.
También se puede usar en la lista de campos de la instrucción Select y en las expresiones con el operador IN (Ver Operadores en SQL Server) y las cláusulas WHERE (Ver Filtrado de datos), ORDER BY (Ver Ordenamientos) y HAVING (Ver Filtros Having).
En este artículo vamos a comparar el uso de Case con un Join, es necesario resaltar que si las opciones posibles del Case cambian, es necesario reescribir la consulta. En un ejercicio se escribe la consulta usando en lugar de Case la función IIF.
Usando la base de datos Northwind
use Northwind
go
Ejercicio 1
Usando Case para la lista de productos y los nombres de las categorias
select P.ProductID as 'Código', P.ProductName as 'Descripción',
Case CategoryID
When 1 then 'Bebidas'
When 2 then 'Condimentos'
When 3 then 'Confecciones'
When 4 then 'Productos diarios'
When 5 then 'Cereales'
When 6 then 'Carnes'
When 7 then 'Conservas'
When 8 then 'Productos marinos' End As Categoría
from dbo.Products As P
go
El costo estimado de la consulta usando Case se puede ver en la siguiente imagen.

Costo: 0.0033744
Usando Join para listar los productos y su categoría (Ver Joins)
Select P.ProductID as 'Código', P.ProductName as 'Descripción',
C.CategoryName AS Categoría
from Products As P
join dbo.Categories As C on P.CategoryID = C.CategoryID
go
El costo estimado de la consulta usando Joins se puede ver en la siguiente imagen.

Costo: 0.0189873
Conclusión
Si comparamos los valores, Case en este caso es es mas rápido, al usar Join la consulta tiene un costo de 5,63 veces mayor, es necesario anotar nuevamente que si las categorías cambian, la consulta usando Case es necesario reescribirla.
Ejercicio 2
Usando las tablas Region y Terrotories con Case
select T.TerritoryID As 'Código', T.TerritoryDescription As 'Territorio',
Region = case T.RegionID
When 1 then 'Este'
When 2 then 'Oeste'
When 3 then 'Norte'
When 4 then 'Sur' End
from dbo.Territories As T
go
El plan de ejecución se muestra en la siguiente imagen.

Costo de la consulta: 0.0033456
Usando Join para listar los territorios y las regiones a las que pertenecen
Select T.TerritoryID as 'Código', T.TerritoryDescription as 'Territorio',
R.RegionDescription AS 'Región'
from dbo.Territories As T
join dbo.Region As R on T.RegionID = R.RegionID
go
El plan de ejecución se muestra en la siguiente imagen.

Costo de la consulta: 0.0248898
Conclusión
Si comparamos los valores, Case en este caso es es mas rápido, al usar Join la consulta tiene un costo de 7,44 veces mayor, es necesario anotar nuevamente que si las regiones cambian, la consulta usando Case es necesario reescribirla.
Ejercicio 3
Listado de las órdenes de agosto de 1997, incluir el nombre de las empresas de envío (Shippers).
Listado de las empresas de envío
select * from dbo.Shippers
go
Las empresas de envío son:
1 Speedy Express (503) 555-9831
2 United Package (503) 555-3199
3 Federal Shipping (503) 555-9931
select
O.OrderID As 'Nº Orden',
Format(O.OrderDate,'dd/MM/yyyy') As 'Fecha',
Courier = case O.ShipVia
When 1 then 'Speedy Express'
When 2 then 'United Package'
When 3 then 'Federal Shipping'
End
from dbo.Orders As O
where Year(O.OrderDate) = 1997 and MONTH(O.OrderDate) = 8
go
El plan de ejecución se muestra en la siguiente imagen.

Costo de la consulta: 0.0183521
El mismo listado usando Joins
select
O.OrderID As 'Nº Orden',
Format(O.OrderDate,'dd/MM/yyyy') As 'Fecha',
S.CompanyName As 'Courier'
from dbo.Orders As O
join dbo.Shippers As S on O.ShipVia = S.ShipperID
where Year(O.OrderDate) = 1997 and MONTH(O.OrderDate) = 8
go
El plan de ejecución se muestra en la siguiente imagen.

Costo de la consulta: 0.0300915
Conclusión
Si comparamos los valores, Case en este caso es es mas rápido, al usar Join la consulta tiene un costo de 1,6 veces mayor, es necesario anotar nuevamente que si las empresas de envío cambian, la consulta usando Case es necesario reescribirla.
Ejercicio 4
Case y la función IIF
Listado de los empleados y la cantidad de órdenes generadas, si la cantidad de órdenes es mayor a 100 el empleado ha cumplido la meta, aparece «Meta cumplida», si la cantidad está entre 50 y 100, está en proceso por lo tanto se muestra el mensaje «En Proceso» y si es menor de 50 es necesario un plan de mejora, mostraremos el mensaje «Plan de mejora». Usaremos Case para una consulta y para la otra el uso de la función IIF.
select
E.EmployeeID,
CONCAT_WS(space(1),E.TitleOfCourtesy, E.FirstName, E.LastName) As 'Empleado',
COUNT(O.OrderID) As 'Cantidad de Órdenes',
Case
when COUNT(O.OrderID)>100 then 'Meta cumplida'
when (COUNT(O.OrderID)<=100 and COUNT(O.OrderID)>=80) then 'En proceso'
else 'Plan de mejora'
End
As 'Resultado'
from dbo.Employees As E
join dbo.Orders As O on E.EmployeeID = O.EmployeeID
group by
E.EmployeeID,
CONCAT_WS(space(1),E.TitleOfCourtesy, E.FirstName, E.LastName)
go
Usando la función IIF
select
E.EmployeeID,
CONCAT_WS(space(1),E.TitleOfCourtesy, E.FirstName, E.LastName) As 'Empleado',
COUNT(O.OrderID) As 'Cantidad de Órdenes',
iif(COUNT(O.OrderID)>100, 'Meta cumplida',
iif(COUNT(O.OrderID)<=100 and COUNT(O.OrderID)>=80, 'En proceso','Plan de mejora'))
As 'Resultado'
from dbo.Employees As E
join dbo.Orders As O on E.EmployeeID = O.EmployeeID
group by
E.EmployeeID,
CONCAT_WS(space(1),E.TitleOfCourtesy, E.FirstName, E.LastName)
go
El resultado de la consulta es el mismo y el plan de ejecución muestra el mismo tiempo de respuesta. La imagen muestra el listado.
