3 lỗi thường gặp khi xử lý NULL trong SQL

Ngày đăng: 08/03/2022

“Ăn gì cũng được”NULL trong SQL, khi nói về 2 thứ có vẻ chẳng liên quan nhưng lại giống nhau đến lạ. Không tin ư? Dưới góc nhìn của chàng trai DA độc thân của chúng ta thì có đấy. Cùng đọc phía dưới nhé. 

Khi tôi cố khớp lệnh với 7749 các món ăn trong sổ tay phòng chống độc thân với trạng thái “Ăn gì cũng được” của crush, tất cả đều trả về FALSE. Trạng thái này làm chúng NULL, một khái niệm gây không ít phiền phức cho các bạn DA khi mới làm việc với SQL. 

Vậy NULL trong SQL là gì?  

NULL là một giá trị đặc biệt có trong tất cả các loại dữ liệu, từ kiểu số, ngày, chuỗi, bit… Nó đại diện cho giá trị “không biết” hoặc “không tồn tại”. Khác với Excel, NULL trong SQL sẽ coi không trùng với số 0 của kiểu số và cũng không trùng với chuỗi trống (‘’) của kiểu chuỗi. Ví dụ bạn có bảng dữ liệu chứa các đối tượng tiềm năng trong công ty; có cột năm sinh. Nếu một bản ghi chứa NULL thì nghĩa là ta không biết đối tượng đó sinh năm nào chứ không phải đối tượng đó sinh năm 0. 

NULL nghĩa là không biết, nên mọi thao tác với NULL đều dẫn đến NULL. Đây là điều các bạn cần ghi nhớ để tránh phiền phức khi có những tính toán xử lý NULL trong SQL và xây dựng những test case liên quan.

Xem video dưới đây để hiểu hơn về NULL và những rủi ro khi làm việc với NULL nhé!

3 đặc tính quan trọng của NULL

Mọi phép toán với NULL đều trả về NULL

Trong ví dụ này, ở bản ghi thứ 2, trường TenDem đang NULL dẫn tới việc ta phép cộng chuỗi nhận giá trị NULL.

Để khắc phục sự cố này, ta có thể sử dụng một số cách thức sau như:

  • Sử dụng hàm CONCAT
  • Sử dụng hàm CONCAT_WS
  • Sử dụng hàm CONCAT_WS kết hợp với NULLIF

Sử dụng CONCAT, ta giải quyết được trường hợp khi cộng chuỗi nhưng kết quả trả về sẽ chứa 2 dấu cách (ở đây là dấu “-“).

Ở cột HovaTen_2, ta sử dụng CONCAT_WS. Dấu “-” bị thừa ra ở bản ghi thứ 2 đã được giải quyết. Do với trường hợp gặp dữ liệu NULL, hàm CONCAT_WS sẽ tự loại kí tự phân cách ở đó. Nhưng với bản ghi thứ 5, trường TenDem là khoảng trắng và nó coi đây là một chuỗi có thể cộng được nên vẫn đưa kí tự phân cách là dấu “-” vào trong kết quả.

Để xử lý vẫn đề ở bản ghi thứ 5, ta phải lồng thêm hàm NULLIF. Cơ chế hoạt động của NULLIF trong trường hợp này là nếu một trường bị rỗng nó sẽ chuyển thành dạng NULL và thực thi như bình thường. Có thể thấy, ở cột HovaTen_3 hàm CONCAT_WS và NULLIF đã xử lý được hết các trường hợp có bản ghi chứa giá trị NULL hay BLANK.

Mọi phép so sánh với NULL đều trả về NULL

Đầu tiên, hãy cùng xem lại bảng dữ liệu mẫu. Bảng dữ liệu này ban đầu có 5 bản ghi.

Tuy nhiên, khi ta thử thực hiện lệnh truy vấn như bên dưới. Kết quả lại bị thiếu mất bản ghi thứ 3. Vì khi truy vấn bảng mà trong mệnh đề WHERE có dùng cột chứa NULL, các bản ghi NULL luôn là ngoại lệ.

Để lấy được các bản ghi này bạn cần dùng “IS NULL”.

Các phép toán tổng hợp dữ liệu không tính đến NULL

Khi dùng các hàm tính toán aggregate (như COUNT, SUM,…), SQL loại bỏ các bản ghi NULL ra trước khi thực hiện do đó tránh được rắc rối khi dính với NULL. Tuy nhiên, trong một số trường hợp, việc loại bỏ NULL dẫn tới việc kết quả trả về không đúng theo logic thông thường.

Bảng dữ liệu DoanhThuChiPhi gồm 10 bản ghi tương ứng với dữ liệu của 10 ngày.

Theo logic thông thường, doanh thu/chi phí trung bình sẽ bằng tổng doanh thu/chi phí chia cho tổng số ngày. Vì thế kết quả đúng sẽ phải là 17.2 và 14.0. Tuy nhiên, khi ta sử dụng hàm AVERAGE, nó tự động bỏ qua những trường chứa giá trị NULL và chỉ chia cho các trường còn lại nên dẫn đến kết quả sai.

Tạm kết

NULL là trạng thái đặc biệt và các bạn mới làm việc với dữ liệu sẽ gặp nhiều bỡ ngỡ. Trên đây là một số đặc tính quan trọng của NULL cũng như một số lưu ý giúp các bạn tránh rủi ro trong quá trình làm việc. Theo dõi thêm để bỏ túi nhiều kiến thức bổ ích nhé!

P/s: Code mẫu viết trên SQL Server kiến thức chung đúng cho các bản SQL khác. 

Chia sẻ bài viết này

Để lại một bình luận

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *

This site uses Akismet to reduce spam. Learn how your comment data is processed.