COALESCE (Transact-SQL)
platí pro:SQL Server
Azure SQL Database
Azure SQL Managed Instance
Azure Synapse Analytics
Analytics Platform System (PDW)
koncový bod SQL Analytics ve službě Microsoft Fabric
Warehouse v Microsoft Fabric
databáze SQL v Microsoft Fabric
Vyhodnotí argumenty v pořadí a vrátí aktuální hodnotu prvního výrazu, který se zpočátku nevyhodnocuje jako NULL
. Následující příklad vrátí třetí hodnotu, protože třetí hodnota je první hodnota, která nemá hodnotu null.
SELECT COALESCE(NULL, NULL, 'third_value', 'fourth_value');
Poznámka
Pokud chcete zřetězení řetězců, použijte místo toho STRING_AGG.
Syntax
COALESCE ( expression [ , ...n ] )
Argumenty
výrazu
Návratové typy
Vrátí datový typ výrazu s nejvyšší prioritou datového typu. Pokud všechny výrazy nejsou nullable, výsledek se zadá jako nenulový.
Poznámky
Pokud jsou všechny argumenty NULL
, vrátí COALESCE
NULL
. Nejméně jedna z hodnot null musí být typ NULL
.
Porovnání funkce COALESCE a CASE
Výraz COALESCE
je syntaktická zkratka výrazu CASE
. To znamená, že optimalizátor dotazů přepíše kód COALESCE(<expression1>, ...n)
jako následující výraz CASE
:
CASE
WHEN (expression1 IS NOT NULL) THEN expression1
WHEN (expression2 IS NOT NULL) THEN expression2
...
ELSE expressionN
END
Vstupní hodnoty (výraz1, výraz2, výrazNatd.) se vyhodnocují vícekrát. Výraz hodnoty, který obsahuje poddotaz, se považuje za nedeterministický a poddotaz se vyhodnotí dvakrát. Tento výsledek je v souladu se standardem SQL. V obou případech se mezi prvním vyhodnocením a nadcházejícími vyhodnoceními můžou vrátit různé výsledky.
Například při spuštění kódu COALESCE((subquery), 1)
se poddotaz vyhodnotí dvakrát. V důsledku toho můžete získat různé výsledky v závislosti na úrovni izolace dotazu. Kód může například vracet NULL
pod úrovní izolace READ COMMITTED
v prostředí s více uživateli. Pokud chcete zajistit vrácení stabilních výsledků, použijte úroveň izolace SNAPSHOT ISOLATION
nebo nahraďte COALESCE
funkcí ISNULL
. Alternativně můžete dotaz přepsat tak, aby se poddotaz nasdílel do dílčího výběru, jak je znázorněno v následujícím příkladu:
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;
Porovnání funkce COALESCE a ISNULL
Funkce ISNULL
a výraz COALESCE
mají podobný účel, ale může se chovat jinak.
Protože
ISNULL
je funkce, vyhodnotí se pouze jednou. Jak jsme popsali dříve, vstupní hodnoty pro výrazCOALESCE
lze vyhodnotit vícekrát.Určení datového typu výsledného výrazu se liší.
ISNULL
používá datový typ prvního parametru aCOALESCE
se řídí pravidly výrazuCASE
k vrácení datového typu hodnoty s nejvyšší prioritou.NULLability výsledného výrazu se liší pro
ISNULL
aCOALESCE
. Návratová hodnotaISNULL
se vždy považuje zaNOT NULL
schopnou (za předpokladu, že návratová hodnota je nenulová). Naproti tomuCOALESCE
s nenulovými parametry se považuje zaNULL
. Výrazy tedyISNULL(NULL, 1)
aCOALESCE(NULL, 1)
, i když jsou stejné, mají různé hodnoty nullability. Tyto hodnoty se liší, pokud tyto výrazy používáte ve počítaných sloupcích, vytváříte klíčová omezení nebo vytváříte návratovou hodnotu skalární uživatelem definované funkce (UDF), aby bylo možné je indexovat, jak je znázorněno v následujícím příkladu: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 );
Ověřování pro
ISNULL
aCOALESCE
se také liší. Například hodnotaNULL
proISNULL
se převede na int ale proCOALESCE
, musíte zadat datový typ.ISNULL
přijímá pouze dva parametry. Naproti tomuCOALESCE
přebírá proměnlivý počet parametrů.
Příklady
Ukázky kódu v tomto článku používají ukázkovou databázi AdventureWorks2022
nebo AdventureWorksDW2022
, kterou si můžete stáhnout z domovské stránky ukázky a komunitní projekty Microsoft SQL Serveru.
A. Vrácení dat z prvního sloupce, který má nenulovou hodnotu
Následující příklad ukazuje, jak COALESCE
vybere data z prvního sloupce, který má nenulovou hodnotu. V tomto příkladu předpokládejme, že tabulka Products
obsahuje tato data:
Name Color ProductNumber
------------ ---------- -------------
Socks, Mens NULL PN1278
Socks, Mens Blue PN1965
NULL White PN9876
Potom spustíme následující dotaz COALESCE
:
SELECT Name,
Color,
ProductNumber,
COALESCE (Color, ProductNumber) AS FirstNotNull
FROM Products;
Tady je sada výsledků.
Name Color ProductNumber FirstNotNull
------------ ---------- ------------- ------------
Socks, Mens NULL PN1278 PN1278
Socks, Mens Blue PN1965 Blue
NULL White PN9876 White
V prvním řádku je hodnota FirstNotNull
PN1278
, nikoli Socks, Mens
. Tato hodnota je tímto způsobem, protože sloupec Name
nebyl zadán jako parametr pro COALESCE
v příkladu.
B. Vrácení nenulové hodnoty v tabulce mezd
V následujícím příkladu tabulka wages
obsahuje tři sloupce, které obsahují informace o roční mzdě zaměstnanců: hodinová mzda, mzda a provize. Zaměstnanec však obdrží pouze jeden typ platby. Chcete-li určit celkovou částku zaplacenou všem zaměstnancům, použijte COALESCE
k získání pouze nenulové hodnoty nalezené v hourly_wage
, salary
a 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
Tady je sada výsledků.
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
Související obsah
- ISNULL (Transact-SQL)
- CASE (Transact-SQL)
- STRING_AGG (Transact-SQL)