COALESCE (Transact-SQL)
Se aplica a:SQL ServerAzure SQL DatabaseAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)Punto de conexión de análisis SQL en Microsoft FabricWarehouse en Microsoft FabricBase de datos SQL de 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
. En el ejemplo siguiente se devuelve el tercer valor porque el tercer valor es el primer valor que no es NULL.
SELECT COALESCE(NULL, NULL, 'third_value', 'fourth_value');
Nota
Si desea concatenar cadenas, use STRING_AGG en su lugar.
Convenciones de sintaxis de Transact-SQL
Sintaxis
COALESCE ( expression [ , ...n ] )
Argumentos
expression
Tipos devueltos
Devuelve el tipo de datos de expresión con la prioridad de tipo de datos más alta. Si todas las expresiones no aceptan valores NULL, el resultado se escribe como que no acepta 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(<expression1>, ...n)
como la siguiente expresión de CASE
:
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.
Dado que
ISNULL
es una función, solo se evalúa una vez. Como se ha descrito anteriormente, los valores de entrada de la expresiónCOALESCE
se pueden evaluar varias veces.La determinación del tipo de datos de la expresión resultante es diferente.
ISNULL
usa el tipo de datos del primer parámetro yCOALESCE
sigue las reglas de expresión deCASE
para devolver el tipo de datos de valor con la prioridad más alta.La nulabilidad de la expresión de resultado es diferente para
ISNULL
yCOALESCE
. El valor devueltoISNULL
siempre se consideraNOT NULL
capaz (suponiendo que el valor devuelto sea un valor que no acepta valores NULL). Por el contrario,COALESCE
con parámetros que no son NULL se consideraNULL
. Por tanto, aunque las expresionesISNULL(NULL, 1)
yCOALESCE(NULL, 1)
son equivalentes, tienen valores de nulabilidad diferentes. Estos valores marcan una diferencia si usa estas expresiones en columnas calculadas, creando restricciones de clave o haciendo que el valor devuelto de una función escalar definida por el usuario (UDF) sea determinista, de modo que se pueda indexar 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 INT 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 INT NULL, col2 AS COALESCE (col1, 0), col3 AS ISNULL(col1, 0) PRIMARY KEY );
Las validaciones de
ISNULL
yCOALESCE
también son diferentes. Por ejemplo, conNULL
, un valorISNULL
se convierte en int, mientras que conCOALESCE
es necesario proporcionar un tipo de datos.ISNULL
toma solo dos parámetros. Por el contrarioCOALESCE
toma un número variable de parámetros.
Ejemplos
Los ejemplos de código de este artículo usan la base de datos de ejemplo de AdventureWorks2022
o AdventureWorksDW2022
, que puede descargar de la página principal de ejemplos de Microsoft SQL Server y proyectos de comunidad.
A. Devolver datos de la primera columna que tiene un valor distinto de NULL
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
A continuación, ejecutamos 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
En la primera fila, el valor de 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
.
B. Devolver el valor distinto de NULL en una tabla de salarios
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, use COALESCE
para recibir solo el valor no NULL que se encuentra 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