Courses
Khi làm việc với dữ liệu thực tế, thiếu giá trị là điều gần như không tránh khỏi. Dù bạn đang làm sạch dữ liệu hay gộp các cột, SQL cung cấp một giải pháp đơn giản nhưng mạnh mẽ: hàm COALESCE(). Hướng dẫn này sẽ cho bạn thấy COALESCE() hoạt động thế nào, khi nào nên dùng và cách áp dụng qua các ví dụ thực tiễn—tất cả chỉ với vài dòng SQL.
COALESCE() trong SQL là gì?
Hàm COALESCE() trong SQL trả về giá trị đầu tiên khác null từ một danh sách biểu thức. Nếu tất cả đều null, nó trả về null. Hàm này thường được dùng để xử lý giá trị thiếu hoặc gộp nhiều cột thành một giá trị dự phòng.
Khi nào bạn nên dùng COALESCE()?
Hàm này hữu ích khi gộp giá trị từ nhiều cột thành một.
Ví dụ, một bảng tên users chứa các giá trị work_email và personal_email của người dùng.
Sử dụng hàm COALESCE(), ta có thể tạo một cột tên email hiển thị work_email của người dùng nếu không phải null. Nếu không, nó hiển thị personal_email.
|
|
|
|
|
|
1 |
angel@datacamp.com |
null |
angel@datacamp.com |
|
2 |
null |
bruce@gmail.com |
bruce@gmail.com |
|
3 |
cath@datacamp.com |
cath@gmail.com |
cath@datacamp.com |
Cú pháp của COALESCE()
COALESCE(value_1, value_2, ...., value_n)
Hàm COALESCE() nhận ít nhất một giá trị (value_1). Nó sẽ trả về giá trị đầu tiên khác null trong danh sách, theo thứ tự từ trái sang phải.
Ví dụ, nó sẽ kiểm tra trước xem value_1 có phải null không. Nếu không, nó trả về value_1. Nếu có, nó kiểm tra value_2 có phải null không. Quá trình tiếp tục cho đến hết danh sách.
COALESCE() có thể dùng với cột, biểu thức hoặc hằng số.
Ví dụ thực tiễn về COALESCE()
Chạy và chỉnh sửa mã từ hướng dẫn trực tuyến này.
Chạy mãVí dụ 1: Thay thế null bằng một hằng số
Xét bảng countries với danh sách quốc gia và ngày quốc khánh của họ. Một số giá trị ngày quốc khánh là null. COALESCE() điền các giá trị thiếu trong national_day bằng chuỗi hằng 'Unknown'.
SELECT
country_id,
name,
national_day,
COALESCE(national_day, 'Unknown') AS national_day_coalesced
FROM countries
ORDER BY country_id
Kết quả như sau:
|
|
|
|
|
|
1 |
Aruba |
null |
Unknown |
|
2 |
Afghanistan |
1919-08-19T00:00:00.000Z |
1919-08-19 |
|
3 |
Angola |
1975-11-11T00:00:00.000Z |
1975-11-11 |
|
4 |
Anguilla |
1967-05-30T00:00:00.000Z |
1967-05-30 |
Lưu ý cách giá trị null trong national_day được thay bằng hằng Unknown.
Ví dụ 2: Lựa chọn giữa hai cột
Chúng ta có một bảng tên products. Bảng chứa tên sản phẩm và mô tả của nó. Một số mô tả quá dài (hơn 60 ký tự). Khi đó, ta thay mô tả bằng tên sản phẩm.
Truy vấn sau dùng CASE để chuyển các mô tả dài thành NULL, sau đó dùng COALESCE() để dự phòng về tên sản phẩm.
SELECT DISTINCT
product_name,
description,
COALESCE(
CASE WHEN
LENGTH(description) >= 60
THEN NULL
ELSE description
END,
product_name) product_name_or_description
FROM products
Kết quả như sau:
product_name |
|
|
|
G.Skill Ripjaws V Series |
"Speed:DDR4-3200,Type:288-pin DIMM,CAS:14Module:4x16GBSize:64GB" |
G.Skill Ripjaws V Series |
|
G.Skill Ripjaws V Series |
"Speed:DDR4-3200,Type:288-pin DIMM,CAS:15Module:4x16GBSize:64GB" |
G.Skill Ripjaws V Series |
|
Asus X99-E-10G WS |
"CPU:LGA2011-3,Form Factor:SSI CEB,RAM Slots:8,Max RAM:128GB" |
"CPU:LGA2011-3,Form Factor:SSI CEB,RAM Slots:8,Max RAM:128GB" |
|
Supermicro X9SRH-7TF |
"CPU:LGA2011,Form Factor:ATX,RAM Slots:8,Max RAM:64GB" |
"CPU:LGA2011,Form Factor:ATX,RAM Slots:8,Max RAM:64GB" |
Lưu ý cách cột product_name_or_description hiển thị product_name nếu description dài. Ngược lại, nó hiển thị description.
Ví dụ 3: Logic dự phòng với nhiều cột
Ta có thể mở rộng ví dụ 2 thêm một bước. Giả sử hiện có hai yêu cầu:
- Nếu độ dài
descriptionnhỏ hơn 60, thì hiển thịdescription. - Nếu không, kiểm tra độ dài
product_namenhỏ hơn 20. Nếu đúng, hiển thịproduct_name. - Nếu không, hiển thị
product.
SELECT DISTINCT
product_name,
description,
COALESCE(
CASE
WHEN LENGTH(description) > 50
THEN NULL
ELSE description
END,
CASE
WHEN LENGTH(product_name) > 14
THEN NULL
ELSE product_name
END,
'product') AS product_name_or_description
FROM products
ORDER BY product_name
Kết quả như sau:
|
|
|
|
|
ADATA ASU800SS-128GT-C |
Series:Ultimate SU800,Type:SSD,Capacity:128GB,Cache:N/A |
product |
|
ADATA ASU800SS-512GT-C |
Series:Ultimate SU800,Type:SSD,Capacity:512GB,Cache:N/A |
product |
|
AMD 100-5056062 |
Chipset:Vega Frontier Edition Liquid,Memory:16GBCore Clock:1.5GHz |
product |
|
AMD 100-505989 |
Chipset:FirePro W9100,Memory:32GBCore Clock:930MHz |
Chipset:FirePro W9100,Memory:32GBCore Clock:930MHz |
Lưu ý cách cột product_name_or_description hiển thị product_name hoặc description tùy theo độ dài của product_name hoặc description.
Các hệ quản trị SQL hỗ trợ
COALESCE() hoạt động trong SQL Server (bắt đầu từ 2008), Azure SQL Database, Azure SQL Data Warehouse, Parallel Data Warehouse, BigQuery và Amazon RedShift.
Các hàm SQL liên quan
Kết luận
Hàm COALESCE() là một công cụ linh hoạt để xử lý giá trị null và đơn giản hóa truy vấn SQL của bạn. Dù bạn đang thay thế dữ liệu thiếu bằng giá trị mặc định hay gộp nhiều cột thành một, COALESCE() giúp giữ cho logic của bạn gọn gàng và dễ đọc.
Sẵn sàng nâng cao kỹ năng SQL? Hãy khám phá các khóa học thân thiện với người mới bắt đầu và hữu ích cho sự nghiệp trên DataCamp:
Câu hỏi thường gặp
Điều gì xảy ra nếu tất cả giá trị trong COALESCE() đều NULL?
Nếu mọi đối số truyền vào hàm COALESCE() đều là NULL, hàm sẽ trả về NULL.
COALESCE() khác gì so với ISNULL() hoặc IFNULL()?
ISNULL()(SQL Server) vàIFNULL()(MySQL, SQLite) chỉ chấp nhận hai đối số.-
COALESCE()có thể chấp nhận nhiều đối số và mang tính tiêu chuẩn hơn giữa các phương ngữ SQL. -
COALESCE()là một phần của tiêu chuẩn ANSI SQL, trong khiISNULL()vàIFNULL()là đặc thù theo hệ quản trị cơ sở dữ liệu.
Tôi có thể dùng COALESCE() với biểu thức hoặc hàm không?
Có, bạn có thể dùng tên cột, literal, hàm hoặc biểu thức bên trong COALESCE().
COALESCE(LOWER(name), 'unknown')Dùng COALESCE() có gây tốn hiệu năng không?
Nhìn chung là không—COALESCE() hiệu quả. Tuy nhiên, nếu bạn dùng nó với các biểu thức phức tạp hoặc trong truy vấn lớn, hệ cơ sở dữ liệu có thể đánh giá nhiều biểu thức hơn mức cần thiết, tùy vào cách viết.
COALESCE() có hoạt động với các kiểu dữ liệu khác nhau không?
Có, nhưng tất cả đối số nên có thể chuyển kiểu ngầm định về cùng một kiểu dữ liệu. Nếu không, tùy vào hệ SQL của bạn, có thể phát sinh lỗi chuyển đổi kiểu.
Tôi có thể lồng các hàm COALESCE() không?
Có. Bạn có thể lồng chúng, dù điều này hiếm khi cần thiết vì COALESCE() vốn đã xử lý nhiều đối số:
COALESCE(col1, COALESCE(col2, 'default'))
Điều này tương đương với:
COALESCE(col1, col2, 'default')