Comparteix a través de


COALESCE (Transact-SQL)

Se aplica a: SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Analytics Platform System (PDW) Punto de conexión de análisis SQL en Microsoft Fabric Almacenamiento en Microsoft Fabric

Evalúa los argumentos en orden y devuelve el valor actual de la primera expresión que inicialmente no se evalúa como NULL. Por ejemplo, SELECT COALESCE(NULL, NULL, 'third_value', 'fourth_value'); devuelve el tercer valor porque el tercer valor es el primer valor que no es NULL.

Convenciones de sintaxis de Transact-SQL

Sintaxis

COALESCE ( expression [ ,...n ] )   

Argumentos

expression
Es una expresión de cualquier tipo.

Tipos de valor devuelto

Devuelve el tipo de datos de expresión con la prioridad de tipo de datos más alta. Si ninguna de las expresiones admiten valores NULL, el resultado tiene un tipo que no admite valores NULL.

Observaciones

Si todos los argumentos son NULL, COALESCE devuelve NULL. Al menos uno de los valores NULL debe ser NULL con tipo.

Comparar COALESCE y CASE

La expresión COALESCE es un método abreviado sintáctico de la expresión CASE. Es decir, el optimizador de consultas vuelve a escribir el código COALESCE(expresión1,...n) como la expresión CASE siguiente:

CASE  
WHEN (expression1 IS NOT NULL) THEN expression1  
WHEN (expression2 IS NOT NULL) THEN expression2  
...  
ELSE expressionN  
END  

Esto significa que los valores de entrada (expresión1, expresión2, expresiónN, etc.) se evalúan varias veces. Una expresión de valor que contiene una subconsulta se considera no determinista, y la subconsulta se evalúa dos veces. El resultado está conforme con el estándar SQL. En cualquier caso, se pueden devolver resultados diferentes entre la primera evaluación y las evaluaciones posteriores.

Por ejemplo, cuando se ejecuta el código COALESCE((subquery), 1), la subconsulta se evalúa dos veces. En consecuencia, podrá obtener resultados diferentes en función del nivel de aislamiento de la consulta. Por ejemplo, en un entorno multiusuario, el código puede devolver NULL en el nivel de aislamiento READ COMMITTED. Para asegurarse de que se devuelven resultados estables, use el nivel de aislamiento SNAPSHOT ISOLATION, o bien reemplace COALESCE por la función ISNULL. Como alternativa, puede volver a escribir la consulta para insertar la subconsulta en una subselección como se muestra en el ejemplo siguiente:

SELECT CASE WHEN x IS NOT NULL THEN x ELSE 1 END  
FROM  
(  
SELECT (SELECT Nullable FROM Demo WHERE SomeCol = 1) AS x  
) AS T;  
  

Comparar COALESCE e ISNULL

La función ISNULL y la expresión COALESCE tienen una finalidad similar, pero se pueden comportar de forma diferente.

  1. Dado que ISNULL es una función, solo se evalúa una vez. Como se describió anteriormente, los valores de entrada de la expresión COALESCE se pueden evaluar varias veces.

  2. La determinación del tipo de datos de la expresión resultante es diferente. ISNULL usa el tipo de datos del primer parámetro, mientras que COALESCE sigue las reglas de la expresión CASE y devuelve el tipo de datos del valor con la prioridad más alta.

  3. La nulabilidad de la expresión de resultado es diferente para ISNULL y COALESCE. El valor devuelto por ISNULL siempre se considera NOT NULL (suponiendo que el valor devuelto no admita valores NULL). Por el contrario, COALESCE con parámetros que no son NULL se considera NULL. Por tanto, aunque las expresiones ISNULL(NULL, 1) y COALESCE(NULL, 1) son equivalentes, tienen valores de nulabilidad diferentes. Estos valores marcan la diferencia si estas expresiones se usan en columnas calculadas, se crean restricciones de clave o se hace que el valor devuelto de un UDF escalar sea determinista para poder indexarlo, como se muestra en el ejemplo siguiente:

    USE tempdb;  
    GO  
    -- This statement fails because the PRIMARY KEY cannot accept NULL values  
    -- and the nullability of the COALESCE expression for col2   
    -- evaluates to NULL.  
    CREATE TABLE #Demo   
    (   
      col1 INTEGER NULL,   
      col2 AS COALESCE(col1, 0) PRIMARY KEY,   
      col3 AS ISNULL(col1, 0)   
    );   
    
    -- This statement succeeds because the nullability of the   
    -- ISNULL function evaluates AS NOT NULL.  
    
    CREATE TABLE #Demo   
    (   
      col1 INTEGER NULL,   
      col2 AS COALESCE(col1, 0),   
      col3 AS ISNULL(col1, 0) PRIMARY KEY   
    );  
    
  4. Las validaciones de ISNULL y COALESCE también son diferentes. Por ejemplo, con ISNULL, un valor NULL se convierte en int, mientras que con COALESCE es necesario proporcionar un tipo de datos.

  5. ISNULL toma solo dos parámetros. Por el contrario COALESCE toma un número variable de parámetros.

Ejemplos

A. Ejecutar un ejemplo sencillo

En el ejemplo siguiente se muestra cómo COALESCE selecciona los datos de la primera columna que tiene un valor no nulo. En este ejemplo se usa la base de datos AdventureWorks2022.

SELECT Name, Class, Color, ProductNumber,  
COALESCE(Class, Color, ProductNumber) AS FirstNotNull  
FROM Production.Product;  

B. Ejecutar un ejemplo complejo

En este ejemplo, la tabla wages incluye tres columnas con información acerca del sueldo anual de los empleados: la tarifa por hora, el salario y la comisión. No obstante, un empleado recibe solo un tipo de sueldo. Para determinar el importe total pagado a todos los empleados, utilice COALESCE para obtener solo los valores no NULL que se encuentran en hourly_wage, salary y commission.

SET NOCOUNT ON;  
GO  
USE tempdb;  
IF OBJECT_ID('dbo.wages') IS NOT NULL  
    DROP TABLE wages;  
GO  
CREATE TABLE dbo.wages  
(  
    emp_id        TINYINT   IDENTITY,  
    hourly_wage   DECIMAL   NULL,  
    salary        DECIMAL   NULL,  
    commission    DECIMAL   NULL,  
    num_sales     TINYINT   NULL  
);  
GO  
INSERT dbo.wages (hourly_wage, salary, commission, num_sales)  
VALUES  
    (10.00, NULL, NULL, NULL),  
    (20.00, NULL, NULL, NULL),  
    (30.00, NULL, NULL, NULL),  
    (40.00, NULL, NULL, NULL),  
    (NULL, 10000.00, NULL, NULL),  
    (NULL, 20000.00, NULL, NULL),  
    (NULL, 30000.00, NULL, NULL),  
    (NULL, 40000.00, NULL, NULL),  
    (NULL, NULL, 15000, 3),  
    (NULL, NULL, 25000, 2),  
    (NULL, NULL, 20000, 6),  
    (NULL, NULL, 14000, 4);  
GO  
SET NOCOUNT OFF;  
GO  
SELECT CAST(COALESCE(hourly_wage * 40 * 52,   
   salary,   
   commission * num_sales) AS money) AS 'Total Salary'   
FROM dbo.wages  
ORDER BY 'Total Salary';  
GO  

Este es el conjunto de resultados.

Total Salary  
------------  
10000.00  
20000.00  
20800.00  
30000.00  
40000.00  
41600.00  
45000.00  
50000.00  
56000.00  
62400.00  
83200.00  
120000.00  
  
(12 row(s) affected)

C. Ejemplo sencillo

En el ejemplo siguiente se muestra cómo COALESCE selecciona los datos de la primera columna que tiene un valor que no es NULL. Para este ejemplo, se supone que la tabla Products contiene estos datos:

Name         Color      ProductNumber  
------------ ---------- -------------  
Socks, Mens  NULL       PN1278  
Socks, Mens  Blue       PN1965  
NULL         White      PN9876

Después, se ejecuta la siguiente consulta COALESCE:

SELECT Name, Color, ProductNumber, COALESCE(Color, ProductNumber) AS FirstNotNull   
FROM Products ;  

Este es el conjunto de resultados.

Name         Color      ProductNumber  FirstNotNull  
------------ ---------- -------------  ------------  
Socks, Mens  NULL       PN1278         PN1278  
Socks, Mens  Blue       PN1965         Blue  
NULL         White      PN9876         White

Observe que en la primera fila, el valor FirstNotNull es PN1278, no Socks, Mens. Esto se debe a que en el ejemplo la columna Name no se especificó como un parámetro para COALESCE.

D. Ejemplo complejo

En el ejemplo siguiente se usa COALESCE para comparar los valores de tres columnas y devolver solo el valor distinto de NULL que se encuentra en las columnas.

CREATE TABLE dbo.wages  
(  
    emp_id        TINYINT   NULL,  
    hourly_wage   DECIMAL   NULL,  
    salary        DECIMAL   NULL,  
    commission    DECIMAL   NULL,  
    num_sales     TINYINT   NULL  
);  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (1, 10.00, NULL, NULL, NULL);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (2, 20.00, NULL, NULL, NULL);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (3, 30.00, NULL, NULL, NULL);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (4, 40.00, NULL, NULL, NULL);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (5, NULL, 10000.00, NULL, NULL);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (6, NULL, 20000.00, NULL, NULL);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (7, NULL, 30000.00, NULL, NULL);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (8, NULL, 40000.00, NULL, NULL);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (9, NULL, NULL, 15000, 3);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (10,NULL, NULL, 25000, 2);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (11, NULL, NULL, 20000, 6);  
  
INSERT INTO dbo.wages (emp_id, hourly_wage, salary, commission, num_sales)  
VALUES (12, NULL, NULL, 14000, 4);  
  
SELECT CAST(COALESCE(hourly_wage * 40 * 52,   
   salary,   
   commission * num_sales) AS DECIMAL(10,2)) AS TotalSalary   
FROM dbo.wages  
ORDER BY TotalSalary;  

Este es el conjunto de resultados.

Total Salary  
------------  
10000.00  
20000.00  
20800.00  
30000.00  
40000.00  
41600.00  
45000.00  
50000.00  
56000.00  
62400.00  
83200.00  
120000.00

Consulte también

ISNULL (Transact-SQL)
CASE (Transact-SQL)