Compartir a través de


CASO (Transact-SQL)

Se aplica a:SQL ServerAzure SQL DatabaseInstancia administrada de Azure SQLAzure Synapse AnalyticsAnalytics Platform System (PDW)Punto de conexión de SQL Analytics en Microsoft FabricAlmacén en Microsoft FabricBase de datos SQL en Microsoft Fabric

Evalúa una lista de condiciones y devuelve una de las varias expresiones de resultado posibles.

La expresión CASE tiene dos formatos:

  • La expresión simpleCASE compara una expresión con un conjunto de expresiones simples para determinar el resultado.

  • La expresión buscadaCASE evalúa un conjunto de expresiones booleanas para determinar el resultado.

Ambos formatos admiten un argumento opcional ELSE .

CASE se puede utilizar en cualquier instrucción o cláusula que permite una expresión válida. Por ejemplo, puede usar CASE en instrucciones como SELECT, UPDATEDELETEy SET, y en cláusulas como <select_list>, IN, WHERE, ORDER BYy HAVING.

Convenciones de sintaxis de Transact-SQL

Syntax

Sintaxis para SQL Server, Azure SQL Database y Azure Synapse Analytics.

-- 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

Sintaxis para el almacenamiento de datos paralelo.

CASE
     WHEN when_expression THEN result_expression [ ...n ]
     [ ELSE else_result_expression ]
END

Arguments

input_expression

La expresión evaluada cuando se utiliza el formato CASE sencillo. input_expression es cualquier expresión válida.

CUANDO when_expression

Una expresión sencilla con la que se compara input_expression cuando se usa el formato CASE sencillo. when_expression es cualquier expresión válida. Los tipos de datos de input_expression y cada when_expression deben ser iguales o deben ser una conversión implícita.

RESULT_EXPRESSION

La expresión devuelta cuando input_expression es igual a when_expression se evalúa como TRUEo Boolean_expression se evalúa como TRUE. result expression es cualquier expresión válida.

SI NO else_result_expression

Expresión devuelta si ninguna operación de comparación se evalúa como TRUE. Si se omite este argumento y ninguna operación de comparación se evalúa como TRUE, CASE devuelve NULL. else_result_expression es cualquier expresión válida. Los tipos de datos de else_result_expression y cada result_expression deben ser iguales o deben ser una conversión implícita.

CUÁNDO Boolean_expression

La expresión booleana que se evalúa cuando se utiliza el formato CASE de búsqueda. Boolean_expression es cualquier expresión booleana válida.

Tipos de retorno

Devuelve el tipo de prioridad más alto del conjunto de tipos de result_expressions y la expresión else_result_expression opcional. Para obtener más información, consulte Precedencia de tipos de datos.

Valores devueltos

Expresión CASE simple

La expresión simple CASE funciona comparando la primera expresión con la expresión de cada WHEN cláusula para la equivalencia. Si estas expresiones son equivalentes, se devuelve la expresión de la THEN cláusula .

  • Permite solo una comprobación de igualdad.

  • En el orden especificado, evalúa input_expression = when_expression para cada WHEN cláusula.

  • Devuelve el result_expression del primer input_expression when_expression = que se evalúa como .TRUE

  • Si no input_expression when_expression = se evalúa como TRUE, el motor de base de datos de SQL Server devuelve el else_result_expression si se especifica una ELSE cláusula o un NULL valor si no se especifica ninguna ELSE cláusula.

Expresión CASE buscada

  • Evalúa, en el orden especificado, Boolean_expression para cada WHEN cláusula.

  • Devuelve result_expression del primer Boolean_expression que se evalúa como TRUE.

  • Si no Boolean_expression se evalúa como TRUE, el motor de base de datos devuelve el else_result_expression si se especifica una ELSE cláusula o un NULL valor si no se especifica ninguna ELSE cláusula.

Remarks

SQL Server solo permite 10 niveles de anidamiento en las expresiones CASE.

La expresión CASE no se puede utilizar para controlar el flujo de ejecución de los bloques de instrucciones, funciones definidas por el usuario, procedimientos almacenados e instrucciones de Transact-SQL. Para obtener una lista de los métodos de control de flujo, consulte Control de flujo.

La expresión CASE evalúa sus condiciones de forma secuencial y se detiene en la primera condición cuya condición se cumple. En algunas situaciones, se evalúa una expresión antes de que una expresión CASE reciba los resultados de la expresión como entrada. Los errores de evaluación de estas expresiones son posibles. Las expresiones de agregado que aparecen en WHEN argumentos para una CASE expresión se evalúan primero y, a continuación, se proporcionan a la CASE expresión. Por ejemplo, la consulta siguiente genera un error de división por cero al generar el valor del MAX agregado. Este paso se produce antes de evaluar la CASE expresión.

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;
GO

Solo debe depender del orden de evaluación de las WHEN condiciones de las expresiones escalares (incluidas las subconsultas no relacionadas que devuelven escalares), no para las expresiones de agregado.

También debe asegurarse de que al menos una de las expresiones de las THEN cláusulas o ELSE no sea la NULL constante. Aunque NULL se puede devolver desde varias expresiones de resultado, no todas ellas pueden ser explícitamente la NULL constante. Si todas las expresiones de resultado usan la constante, se devuelve el NULL error 8133.

Examples

Los ejemplos de código de este artículo usan la base de datos de ejemplo de AdventureWorks2025 o AdventureWorksDW2025, que puede descargar de la página principal de Ejemplos de Microsoft SQL Server y proyectos de comunidad.

A. Uso de una instrucción SELECT con una expresión CASE sencilla

En una instrucción SELECT, una expresión CASE sencilla solo permite una comprobación de igualdad; no se pueden hacer otras comparaciones. En este ejemplo se utiliza la expresión CASE para cambiar la presentación de categorías de línea de productos con el fin de hacerla más comprensible.

USE AdventureWorks2022;
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. Uso de una instrucción SELECT con una expresión CASE de búsqueda

En una instrucción SELECT, la expresión CASE de búsqueda permite sustituir valores en el conjunto de resultados basándose en los valores de comparación. En el ejemplo siguiente se presenta el precio de venta como un comentario basado en el intervalo de precios de un producto.

USE AdventureWorks2022;
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. Uso de CASE en una cláusula ORDER BY

En los ejemplos siguientes se usa la CASE expresión en una ORDER BY cláusula para determinar el criterio de ordenación de las filas en función de un valor de columna determinado. En el primer ejemplo se evalúe 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 según el BusinessEntityID. Los empleados que tienen la columna SalariedFlag establecida en 0 se devuelven en orden ascendente según el BusinessEntityID.

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

En el segundo ejemplo, el conjunto de resultados se ordena según la columna TerritoryName cuando la columna CountryRegionName es igual a 'Estados Unidos' y según la columna CountryRegionName en las demás filas.

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;
GO

D. Uso de CASE en una instrucción UPDATE

En el ejemplo siguiente se usa la CASE expresión en una UPDATE instrucción para determinar el valor establecido para la columna VacationHours para los empleados con 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 OUTPUT cláusula se usa para mostrar los valores antes y después de vacaciones.

USE AdventureWorks2022;
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;
GO

E. Uso de CASE en una instrucción SET

En el ejemplo siguiente se usa la CASE expresión en una SET instrucción de la función dbo.GetContactInfocon valores de tabla . En la base de datos AdventureWorks2025, todos los datos relacionados con las personas están almacenados en la tabla Person.Person. Por ejemplo, la persona puede ser un empleado, un representante del proveedor o un cliente. La función devuelve el nombre (FirstName) y el nombre de familia (LastName) de un determinado BusinessEntityID y el tipo de contacto de esa persona. La CASE expresión de la SET instrucción determina el valor que se va a mostrar para la columna ContactType en función de la existencia de la BusinessEntityID columna en las Employeetablas , Vendoro Customer .

USE AdventureWorks2022;
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);
GO

F. Uso de CASE en una cláusula HAVING

En el ejemplo siguiente se usa la CASE expresión en una HAVING cláusula para restringir las filas devueltas por la SELECT instrucción . La instrucción devuelve el precio por hora para cada puesto en la tabla HumanResources.Employee. La HAVING cláusula restringe los títulos a los que tienen los empleados salarios con una tasa máxima de pago superior a 40 dólares, o empleados no asignados con una tasa máxima de pago superior a 15 dólares.

USE AdventureWorks2022;
GO

SELECT JobTitle,
    MAX(ph1.Rate) AS MaximumRate
FROM HumanResources.Employee AS e
INNER JOIN HumanResources.EmployeePayHistory AS ph1
    ON e.BusinessEntityID = ph1.BusinessEntityID
GROUP BY JobTitle
HAVING (
    MAX(CASE
            WHEN SalariedFlag = 1 THEN ph1.Rate
            ELSE NULL
        END) > 40.00
    OR MAX(CASE
            WHEN SalariedFlag = 0 THEN ph1.Rate
            ELSE NULL
        END) > 15.00
)
ORDER BY MaximumRate DESC;
GO

G. Uso de una expresión CASE anidada para clasificar los resultados

En el ejemplo siguiente se usa una expresión anidada CASE para clasificar productos basados en ListPrice. Si un precio de lista de productos supera los 1000 dólares, se considera High-end. Los productos restantes se clasifican en una expresión anidada CASE basada en ProductLine y ListPrice.

USE AdventureWorks2022;
GO

SELECT 
    ProductNumber,
    Name,
    ListPrice,
    PriceCategory = 
        CASE 
            WHEN ListPrice > 1000 THEN 'High-end'
            ELSE 
                CASE ProductLine
                    WHEN 'R' THEN
                        CASE 
                            WHEN ListPrice > 500 THEN 'Premium Road'
                            ELSE 'Standard Road'
                        END
                    WHEN 'M' THEN
                        CASE 
                            WHEN ListPrice > 500 THEN 'Premium Mountain'
                            ELSE 'Standard Mountain'
                        END
                    WHEN 'T' THEN 'Touring'
                    ELSE 'Other'
                END
        END
FROM Production.Product
ORDER BY ListPrice DESC;

Ejemplos: Azure Synapse Analytics y Sistema de la plataforma de análisis (PDW)

H. Uso de una instrucción SELECT con una expresión CASE

Dentro de una SELECT instrucción , la CASE expresión permite reemplazar los valores en el conjunto de resultados en función de los valores de comparación. En este ejemplo se utiliza la expresión CASE para cambiar la presentación de categorías de línea de productos con el fin de hacerla más comprensible. Cuando no existe un valor, se muestra el texto Not for sale .

SELECT ProductAlternateKey,
    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,
    EnglishProductName
FROM dbo.DimProduct
ORDER BY ProductKey;
GO

I. Uso de CASE en una instrucción UPDATE

En el ejemplo siguiente se usa la CASE expresión en una UPDATE instrucción para determinar el valor establecido para la columna VacationHours para los empleados con 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.

UPDATE dbo.DimEmployee
SET VacationHours = (
        CASE
            WHEN ((VacationHours - 10.00) < 0) THEN VacationHours + 40
            ELSE (VacationHours + 20.00)
            END
        )
WHERE SalariedFlag = 0;
GO