Trino SQL Bài học 10: Xử lý giá trị NULL (IS NULL, COALESCE, NULLIF)
Mục tiêu bài học:
-
Hiểu đúng bản chất của
NULLtrong thế giới cơ sở dữ liệu quan hệ và phân tán. -
Nắm vững cách lọc và đối chiếu các bản ghi chứa dữ liệu khuyết thiếu một cách an toàn.
-
Sử dụng thành thạo
COALESCEđể thiết lập giá trị mặc định (fallback). -
Sử dụng
NULLIFđể tránh các lỗi tính toán nghiêm trọng (như lỗi chia cho 0).
1. Bản chất của NULL (Sự vô định)
Sai lầm lớn nhất của người mới học SQL là coi NULL tương đương với số 0 hoặc một chuỗi rỗng ('').
Trong chuẩn ANSI SQL (và Trino tuân thủ tuyệt đối), NULL mang ý nghĩa là "Không xác định" (Unknown) hoặc "Khuyết thiếu" (Missing).
Bởi vì NULL là vô định, bạn không thể mang sự vô định ra so sánh với bất kỳ thứ gì, kể cả với chính nó.
-
10 > NULLKết quả làUNKNOWN. -
NULL = NULLKết quả làUNKNOWN.
Nếu kết quả của mệnh đề WHERE là UNKNOWN, Trino sẽ loại bỏ dòng dữ liệu đó (giống hệt như khi kết quả là FALSE).
2. Nhận diện an toàn với IS NULL / IS NOT NULL
Vì toán tử = không có tác dụng với NULL, bạn bắt buộc phải dùng toán tử chuyên biệt IS NULL để kiểm tra sự tồn tại của dữ liệu khuyết thiếu.
Lọc các bản ghi bị thiếu dữ liệu:
Tìm các khách hàng chưa được cập nhật số điện thoại.
SQL
SELECT name, phone
FROM tpch.tiny.customer
WHERE phone IS NULL;
Lọc các bản ghi có dữ liệu hợp lệ:
Tìm các khách hàng đã có số điện thoại.
SQL
SELECT name, phone
FROM tpch.tiny.customer
WHERE phone IS NOT NULL;
Lưu ý: Tuyệt đối không viết WHERE phone = NULL hay WHERE phone <> NULL. Trino sẽ không báo lỗi cú pháp, nhưng truy vấn của bạn sẽ luôn trả về 0 dòng kết quả (Empty Set).
3. Lấp đầy khoảng trống với COALESCE
Khi trình bày dữ liệu lên Dashboard hoặc trả API về cho Frontend, việc hiển thị chữ NULL trống hoác thường gây trải nghiệm không tốt, hoặc gây lỗi Null Pointer Exception ở hệ thống downstream.
Hàm COALESCE(value1, value2, ..., value_n) sẽ duyệt qua danh sách các đối số từ trái sang phải và trả về giá trị đầu tiên KHÔNG PHẢI là NULL.
SQL
-- Nếu số điện thoại bị NULL, trả về chuỗi 'Chưa cập nhật'
SELECT
name,
COALESCE(phone, 'Chưa cập nhật') AS contact_info
FROM tpch.tiny.customer;
Bạn có thể truyền vào nhiều đối số. Hàm sẽ liên tục "rơi" (fallback) xuống mức tiếp theo cho đến khi tìm được dữ liệu thực.
SQL
-- Lấy số điện thoại di động, nếu NULL thì lấy điện thoại bàn,
-- nếu vẫn NULL thì lấy email, cuối cùng mới trả về 'No Contact'.
SELECT
name,
COALESCE(mobile_phone, desk_phone, email, 'No Contact') AS primary_contact
FROM users;
Ràng buộc của Trino: Tất cả các đối số truyền vào COALESCE phải có cùng kiểu dữ liệu. Bạn không thể truyền tham số đầu là kiểu số nguyên (INTEGER) và tham số dự phòng là chuỗi (VARCHAR).
4. Chủ động tạo NULL với NULLIF
Nếu COALESCE dùng để "xóa" NULL, thì NULLIF(value1, value2) lại dùng để "tạo ra" NULL.
Hàm này so sánh hai giá trị:
-
Nếu
value1 = value2, trả vềNULL. -
Nếu
value1 <> value2, trả vềvalue1.
Ứng dụng thực tế lớn nhất: Tránh lỗi chia cho 0 (Divide by Zero).
Trong tính toán tài chính, nếu bạn lấy doanh thu chia cho số lượng (nhưng số lượng bằng 0), Trino sẽ lập tức báo lỗi và dừng (fail) toàn bộ tiến trình truy vấn.
Thay vì viết hàm IF/ELSE phức tạp, bạn dùng NULLIF để biến số 0 thành NULL. Trong toán học của SQL, một số chia cho NULL sẽ ra kết quả NULL (không gây gián đoạn hệ thống).
SQL
-- Tính đơn giá trung bình: tổng tiền / số lượng
-- Nếu quantity = 0, NULLIF biến nó thành NULL. Phép chia sẽ trả về NULL một cách an toàn.
SELECT
orderkey,
totalprice,
quantity,
totalprice / NULLIF(quantity, 0) AS unit_price
FROM order_details;
5. Cạm bẫy của NULL trong tính toán và tổng hợp
Bạn cần nhớ hai quy tắc toán học quan trọng khi dữ liệu có chứa NULL:
-
Phép toán học thông thường lan truyền NULL: Bất kỳ phép cộng, trừ, nhân, chia nào với
NULLđều raNULL. (Ví dụ:10 + 5 + NULL = NULL). Nếu bạn cần cộng dồn, hãy bọcCOALESCExung quanh. -
Các hàm tổng hợp (Aggregate) bỏ qua NULL: Các hàm như
SUM(),AVG(),COUNT(cột)sẽ tự động phớt lờ các dòng có giá trịNULL. (Ví dụ: Trung bình cộngAVG()sẽ chỉ lấy tổng chia cho số lượng các dòng có chứa dữ liệu thực).
(Chi tiết về hàm tổng hợp sẽ được trình bày sâu hơn ở Bài 16).
All rights reserved