COALESCE (Transact-SQL)
Berlaku untuk: Titik akhir analitik SQL Server Azure SQL Database Azure SQL Managed Instance Azure Synapse Analytics Platform System (PDW) SQL di Microsoft Fabric Warehouse di Microsoft Fabric
Mengevaluasi argumen secara berurutan dan mengembalikan nilai ekspresi pertama saat ini yang awalnya tidak dievaluasi ke NULL
. Misalnya, SELECT COALESCE(NULL, NULL, 'third_value', 'fourth_value');
mengembalikan nilai ketiga karena nilai ketiga adalah nilai pertama yang bukan null.
Sintaks
COALESCE ( expression [ ,...n ] )
Argumen
expression
Adalah ekspresi dari jenis apa pun.
Jenis Kembalian
Mengembalikan tipe data ekspresi dengan prioritas tipe data tertinggi. Jika semua ekspresi tidak dapat diulang, hasilnya dititikkan sebagai tidak dapat diulang.
Keterangan
Jika semua argumen adalah NULL
, COALESCE
mengembalikan NULL
. Setidaknya salah satu nilai null harus diketik NULL
.
Membandingkan COALESCE dan CASE
Ekspresi COALESCE
adalah pintasan sintik untuk CASE
ekspresi. Artinya, kode COALESCE
(ekspresi1,... n) ditulis ulang oleh pengoptimal kueri sebagai ekspresi berikut CASE
:
CASE
WHEN (expression1 IS NOT NULL) THEN expression1
WHEN (expression2 IS NOT NULL) THEN expression2
...
ELSE expressionN
END
Dengan demikian, nilai input (ekspresi1, ekspresi2, ekspresiN, dan sebagainya) dievaluasi beberapa kali. Ekspresi nilai yang berisi subkueri dianggap tidak deterministik dan subkueri dievaluasi dua kali. Hasil ini sesuai dengan standar SQL. Dalam kedua kasus, hasil yang berbeda dapat dikembalikan antara evaluasi pertama dan evaluasi yang akan datang.
Misalnya, ketika kode COALESCE((subquery), 1)
dijalankan, subkueri dievaluasi dua kali. Akibatnya, Anda bisa mendapatkan hasil yang berbeda tergantung pada tingkat isolasi kueri. Misalnya, kode dapat kembali NULL
di READ COMMITTED
bawah tingkat isolasi di lingkungan multi-pengguna. Untuk memastikan hasil yang stabil dikembalikan, gunakan SNAPSHOT ISOLATION
tingkat isolasi, atau ganti COALESCE
dengan ISNULL
fungsi . Sebagai alternatif, Anda dapat menulis ulang kueri untuk mendorong subkueri ke subpilih seperti yang ditunjukkan dalam contoh berikut:
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;
Membandingkan COALESCE dan ISNULL
Fungsi ISNULL
dan COALESCE
ekspresi memiliki tujuan yang sama tetapi dapat berperilaku berbeda.
Karena
ISNULL
merupakan fungsi, fungsi ini hanya dievaluasi sekali. Seperti yang dijelaskan di atas, nilai input untukCOALESCE
ekspresi dapat dievaluasi beberapa kali.Penentuan jenis data dari ekspresi yang dihasilkan berbeda.
ISNULL
menggunakan jenis data parameter pertama,COALESCE
mengikutiCASE
aturan ekspresi dan mengembalikan jenis data nilai dengan prioritas tertinggi.Nullabilitas ekspresi hasil berbeda untuk
ISNULL
danCOALESCE
. NilaiISNULL
yang dikembalikan selalu dianggap NOT NULLable (dengan asumsi nilai yang dikembalikan adalah nilai yang tidak dapat diubah ke null). Sebaliknya,COALESCE
dengan parameter non-null dianggap sebagaiNULL
. Jadi ekspresiISNULL(NULL, 1)
danCOALESCE(NULL, 1)
, meskipun sama, memiliki nilai nullability yang berbeda. Nilai-nilai ini membuat perbedaan jika Anda menggunakan ekspresi ini dalam kolom komputasi, membuat batasan kunci atau membuat nilai pengembalian deterministik UDF skalar sehingga dapat diindeks seperti yang ditunjukkan dalam contoh berikut: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 );
Validasi untuk
ISNULL
danCOALESCE
juga berbeda. Misalnya,NULL
nilai untukISNULL
dikonversi menjadi int meskipun untukCOALESCE
, Anda harus menyediakan jenis data.ISNULL
hanya mengambil dua parameter.COALESCE
Sebaliknya mengambil jumlah parameter variabel.
Contoh
J. Menjalankan contoh sederhana
Contoh berikut menunjukkan cara COALESCE
memilih data dari kolom pertama yang memiliki nilai nonnull. Contoh ini menggunakan database AdventureWorks2022.
SELECT Name, Class, Color, ProductNumber,
COALESCE(Class, Color, ProductNumber) AS FirstNotNull
FROM Production.Product;
B. Menjalankan contoh kompleks
Dalam contoh berikut, wages
tabel menyertakan tiga kolom yang berisi informasi tentang upah tahunan karyawan: upah per jam, gaji, dan komisi. Namun, seorang karyawan hanya menerima satu jenis gaji. Untuk menentukan jumlah total yang dibayarkan kepada semua karyawan, gunakan COALESCE
untuk hanya menerima nilai nonnull yang ditemukan di hourly_wage
, , salary
dan 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
Berikut set hasilnya.
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: Contoh Sederhana
Contoh berikut menunjukkan cara COALESCE
memilih data dari kolom pertama yang memiliki nilai non-null. Asumsikan untuk contoh ini bahwa Products
tabel berisi data ini:
Name Color ProductNumber
------------ ---------- -------------
Socks, Mens NULL PN1278
Socks, Mens Blue PN1965
NULL White PN9876
Kami kemudian menjalankan kueri COALESCE berikut:
SELECT Name, Color, ProductNumber, COALESCE(Color, ProductNumber) AS FirstNotNull
FROM Products ;
Berikut set hasilnya.
Name Color ProductNumber FirstNotNull
------------ ---------- ------------- ------------
Socks, Mens NULL PN1278 PN1278
Socks, Mens Blue PN1965 Blue
NULL White PN9876 White
Perhatikan bahwa di baris pertama, nilainya FirstNotNull
adalah PN1278
, bukan Socks, Mens
. Nilai ini adalah cara ini karena Name
kolom tidak ditentukan sebagai parameter untuk COALESCE
dalam contoh.
D: Contoh Kompleks
Contoh berikut menggunakan COALESCE
untuk membandingkan nilai dalam tiga kolom dan hanya mengembalikan nilai non-null yang ditemukan di kolom.
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;
Berikut set hasilnya.
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