Sunteți pe pagina 1din 8

CASE (Transact-SQL)

Personas que lo han encontrado til: 3 de 4 - Valorar este tema Evala una lista de condiciones y devuelve una de las varias expresiones de resultado posibles. La expresin CASE tiene dos formatos: La expresin CASE sencilla compara una expresin con un conjunto de expresiones sencillas para determinar el resultado. La expresin CASE buscada evala un conjunto de expresiones booleanas para determinar el resultado.

Ambos formatos admiten un argumento ELSE opcional. CASE se puede utilizar en cualquier instruccin o clusula que permite una expresin vlida. Por ejemplo, puede utilizar CASE en instrucciones como SELECT, UPDATE, DELETE y SET, y en clusulas como select_list, IN, WHERE, ORDER BY y HAVING. Convenciones de sintaxis de Transact-SQL

Sintaxis
Simple CASE expression: CASE input_expression WHEN when_expression THEN result_expression [ ...n ] [ ELSE else_result_expression ] END Searched CASE expression: CASE WHEN Boolean_expression THEN result_expression [ ...n ] [ ELSE else_result_expression ] END

Argumentos
input_expression Es la expresin evaluada cuando se utiliza el formato CASE sencillo. input_expression es cualquier expresin vlida. WHEN when_expression

Es una expresin sencilla con la que se compara input_expression cuando se utiliza el formato CASE sencillo. when_expression es cualquier expresin vlida. Los tipos de datos de input_expression y cada when_expression deben ser iguales o deben ser una conversin implcita. THEN result_expression Es la expresin devuelta cuando input_expression es igual que when_expression se evala como TRUE o Boolean_expression se evala como TRUE. result expression es cualquier expresin vlida. ELSE else_result_expression Es la expresin que se devuelve si ninguna comparacin se evala como TRUE. Si se omite este argumento y ninguna comparacin se evala como TRUE, CASE devuelve NULL. else_result_expression es cualquier expresin vlida. Los tipos de datos de else_result_expression y cualquier result_expression deben ser iguales o deben ser una conversin implcita. WHEN Boolean_expression Es la expresin booleana que se evala cuando se utiliza el formato CASE de bsqueda. Boolean_expression es cualquier expresin booleana vlida.

Tipos de valor devueltos


Devuelve el tipo de prioridad ms alto del conjunto de tipos de result_expressions y la expresin else_result_expression opcional. Para obtener ms informacin, vea Prioridad de tipo de datos (Transact-SQL).

Valores devueltos
Expresin CASE simple: La expresin CASE simple compara la primera expresin con la expresin de cada clusula WHEN para determinar si se da alguna equivalencia. Si estas expresiones son equivalentes, se devolver la expresin de la clusula THEN. Permite solo una comprobacin de igualdad. Evala input_expression y, en el orden especificado, la expresin input_expression = when_expression para cada clusula WHEN. Devuelve result_expression de la primera input_expression = when_expression que se evala como TRUE. Si input_expression = when_expression no se evala como TRUE, Motor de base de datos de SQL Server devuelve else_result_expression si se especifica una clusula ELSE, o bien un valor NULL si no se especifica ninguna clusula ELSE.

Expresin CASE buscada: Evala, en el orden especificado, Boolean_expression para cada clusula WHEN. Devuelve result_expression de la primera Boolean_expression que se evala como TRUE. Si Boolean_expression se evala como TRUE, Motor de base de datos devuelve else_result_expression si se especifica una clusula ELSE, o bien un valor NULL si no se especifica ninguna clusula ELSE.

Comentarios
SQL Server solo permite 10 niveles de anidamiento en las expresiones CASE. La expresin CASE no se puede utilizar para controlar el flujo de ejecucin de los bloques de instrucciones, funciones definidas por el usuario, procedimientos almacenados e instrucciones de Transact-SQL. Para obtener una lista de los mtodos de control de flujo, vea Lenguaje de control de flujo (Transact-SQL). La instruccin CASE devuelve las condiciones de forma secuencial y se detiene en la primera condicin cuya condicin se cumple. En algunas situaciones, se evala una expresin antes de que una instruccin CASE reciba los resultados de la expresin como entrada. Los errores de evaluacin de estas expresiones son posibles. Las expresiones de agregado que aparecen en los argumentos WHEN para una instruccin CASE se evalan primero y, a continuacin, se proporcionan a la instruccin CASE. Por ejemplo, la siguiente consulta genera un error de divisin por cero al obtener el valor de agregado MAX. Esto ocurre antes de evaluar la expresin CASE. Transact-SQL WITH Data (value) AS ( SELECT 0 UNION ALL SELECT 1 ) SELECT CASE WHEN MIN(value) <= 0 THEN 0 WHEN MAX(1/value) >= 100 THEN 1 END FROM Data ; Debe depender solo del orden de evaluacin de las condiciones WHEN para las expresiones escalares (incluidas las subconsultas no correlacionadas que devuelven escalares), no para las expresiones de agregado.

Ejemplos

A.Usar una instruccin SELECT con una expresin CASE sencilla


En una instruccin SELECT, una expresin CASE sencilla solo permite una comprobacin de igualdad; no se pueden hacer otras comparaciones. En este ejemplo se utiliza la expresin CASE para cambiar la presentacin de categoras de lnea de productos con el fin de hacerla ms comprensible. Transact-SQL USE AdventureWorks2012; 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

Transact-SQL USE AdventureWorks2012; 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

B.Usar una instruccin SELECT con una expresin CASE de bsqueda


En una instruccin SELECT, la expresin CASE de bsqueda permite sustituir valores en el conjunto de resultados basndose en los valores de comparacin. En el ejemplo siguiente se presenta el precio de venta como un comentario basado en el intervalo de precios de un producto. Transact-SQL USE AdventureWorks2012; GO SELECT ProductNumber, Name, "Price Range" =

CASE WHEN ListPrice = 0 THEN 'Mfg item - not for resale' WHEN ListPrice < 50 THEN 'Under $50' WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250' WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000' ELSE 'Over $1000' END FROM Production.Product ORDER BY ProductNumber ; GO

C.Usar CASE para reemplazar la funcin IIf que se utiliza en Microsoft Access
CASE proporciona una funcionalidad similar a la funcin IIf de Microsoft Access. En el ejemplo siguiente se muestra una consulta sencilla que utiliza IIf para proporcionar un valor de salida para la columnaTelephoneInstructions en una tabla de Access denominada db1.ContactInfo. SELECT FirstName, LastName, TelephoneNumber, IIf(IsNull(TelephoneInstructions),"Any time", TelephoneInstructions) AS [When to Contact] FROM db1.ContactInfo; En el siguiente ejemplo se usa CASE para proporcionar un valor de salida para la columna TelephoneSpecialInstructions de la vista AdventureWorks2012 , Person.vAdditionalContactInfo. Transact-SQL USE AdventureWorks2012; GO SELECT FirstName, LastName, TelephoneNumber, "When to Contact" = CASE WHEN TelephoneSpecialInstructions IS NULL THEN 'Any time' ELSE TelephoneSpecialInstructions END FROM Person.vAdditionalContactInfo;

D.Usar CASE en una clusula ORDER BY


En los ejemplos siguientes se utiliza la expresin CASE en una clusula ORDER BY para determinar el criterio de ordenacin de las filas segn el valor de una columna dada. En el primer ejemplo se evale el valor de la columna SalariedFlag de la tabla HumanResources.Employee. Los empleados que tienen la columna SalariedFlag establecida en 1 se devuelven en orden descendente segn el EmployeeID. Los empleados que tienen la columna SalariedFlag establecida en 0 se devuelven en orden ascendente segn el EmployeeID. En el segundo ejemplo, el conjunto de resultados se ordena segn la columna TerritoryName cuando la columna CountryRegionName es igual a 'United States' y segn la columna CountryRegionName en las dems filas.

Transact-SQL SELECT BusinessEntityID, SalariedFlag FROM HumanResources.Employee ORDER BY CASE SalariedFlag WHEN 1 THEN BusinessEntityID END DESC ,CASE WHEN SalariedFlag = 0 THEN BusinessEntityID END; GO

Transact-SQL SELECT BusinessEntityID, LastName, TerritoryName, CountryRegionName FROM Sales.vSalesPerson WHERE TerritoryName IS NOT NULL ORDER BY CASE CountryRegionName WHEN 'United States' THEN TerritoryName ELSE CountryRegionName END;

E.Usar CASE en una instruccin UPDATE


En el ejemplo siguiente se utiliza la expresin CASE en una instruccin UPDATE para determinar el valor que est establecido en la columna VacationHours para los empleados con el valor de SalariedFlag establecido en 0. Al restar 10 horas de VacationHours da un valor negativo, VacationHours se incrementa en 40 horas; de lo contrario, VacationHours se incrementa en 20 horas. La clusula OUTPUT se utiliza para mostrar los valores de las vacaciones antes y despus. Transact-SQL USE AdventureWorks2012; GO UPDATE HumanResources.Employee SET VacationHours = ( CASE WHEN ((VacationHours - 10.00) < 0) THEN VacationHours + 40 ELSE (VacationHours + 20.00) END ) OUTPUT Deleted.BusinessEntityID, Deleted.VacationHours AS BeforeValue, Inserted.VacationHours AS AfterValue WHERE SalariedFlag = 0;

F.Usar CASE en una instruccin SET


En el ejemplo siguiente se utiliza la expresin CASE en una instruccin SET en la funcin con valores de tabla dbo.GetContactInfo. En la base de datos AdventureWorks2012 , todos los datos relacionados con las personas estn almacenados en la tabla Person.Person. Por ejemplo, la persona puede ser un empleado, un representante de un proveedor o un consumidor. La funcin devuelve el nombre y el apellido de unBusinessEntityID determinado y el tipo de contacto para esa persona. La expresin CASE en la instruccin SET determina el valor que se va a mostrar para la

columna ContactType segn la existencia de la columnaBusinessEntityID en las tablas Employee, Vendor o Customer. Transact-SQL USE AdventureWorks2012; GO CREATE FUNCTION dbo.GetContactInformation(@BusinessEntityID int) RETURNS @retContactInformation TABLE ( BusinessEntityID int NOT NULL, FirstName nvarchar(50) NULL, LastName nvarchar(50) NULL, ContactType nvarchar(50) NULL, PRIMARY KEY CLUSTERED (BusinessEntityID ASC) ) AS -- Returns the first name, last name and contact type for the specified contact. BEGIN DECLARE @FirstName nvarchar(50), @LastName nvarchar(50), @ContactType nvarchar(50); -- Get common contact information SELECT @BusinessEntityID = BusinessEntityID, @FirstName = FirstName, @LastName = LastName FROM Person.Person WHERE BusinessEntityID = @BusinessEntityID; SET @ContactType = CASE -- Check for employee WHEN EXISTS(SELECT * FROM HumanResources.Employee AS e WHERE e.BusinessEntityID = @BusinessEntityID) THEN 'Employee' -- Check for vendor WHEN EXISTS(SELECT * FROM Person.BusinessEntityContact AS bec WHERE bec.BusinessEntityID = @BusinessEntityID) THEN 'Vendor' -- Check for store WHEN EXISTS(SELECT * FROM Purchasing.Vendor AS v WHERE v.BusinessEntityID = @BusinessEntityID) THEN 'Store Contact' -- Check for individual consumer WHEN EXISTS(SELECT * FROM Sales.Customer AS c WHERE c.PersonID = @BusinessEntityID) THEN 'Consumer' END;

-- Return the information to the caller IF @BusinessEntityID IS NOT NULL BEGIN INSERT @retContactInformation SELECT @BusinessEntityID, @FirstName, @LastName, @ContactType; END; RETURN; END; GO SELECT BusinessEntityID, FirstName, LastName, ContactType FROM dbo.GetContactInformation(2200); GO SELECT BusinessEntityID, FirstName, LastName, ContactType FROM dbo.GetContactInformation(5);

G.Usar CASE en una clusula HAVING


En el ejemplo siguiente se utiliza la expresin CASE en una clusula HAVING para restringir las filas devueltas por la instruccin SELECT. La instruccin devuelve el precio por hora mximo para cada puesto en la tablaHumanResources.Employee. La clusula HAVING restringe los ttulos a aquellos que tienen los hombres con una tasa de pago mxima mayor que 40 dlares o las mujeres con una tasa de pago mxima mayor que 42 dlares. Transact-SQL USE AdventureWorks2012; GO SELECT JobTitle, MAX(ph1.Rate)AS MaximumRate FROM HumanResources.Employee AS e JOIN HumanResources.EmployeePayHistory AS ph1 ON e.BusinessEntityID = ph1.Busine ssEntityID GROUP BY JobTitle HAVING (MAX(CASE WHEN Gender = 'M' THEN ph1.Rate ELSE NULL END) > 40.00 OR MAX(CASE WHEN Gender = 'F' THEN ph1.Rate ELSE NULL END) > 42.00) ORDER BY MaximumRate DESC;