CodeGym /Các khóa học /SQL SELF /Những lỗi thường gặp khi làm việc với NULL

Những lỗi thường gặp khi làm việc với NULL

SQL SELF
Mức độ , Bài học
Có sẵn

Trong bài này tụi mình sẽ hiểu rõ hơn về người bạn bí ẩn NULL. Tất nhiên, lỗi của bạn khi làm việc với nó vẫn còn ở phía trước, nhưng... biết trước là chuẩn bị tốt. Cùng xem qua vài lỗi điển hình liên quan đến NULL nhé.

Lỗi 1: Dùng toán tử = thông thường để kiểm tra NULL

Có lẽ đây là lỗi phổ biến nhất của newbie SQL — thử dùng toán tử = để kiểm tra giá trị có phải NULL không.

Chuyện gì xảy ra?

SELECT *
FROM students
WHERE age = NULL;

Nghĩ rằng câu này sẽ trả về tất cả sinh viên có tuổi chưa xác định, bạn sẽ thất vọng: truy vấn này không trả về gì cả. Tại sao? Bởi vì NULL không phải là một giá trị, nên các toán tử so sánh thông thường không hoạt động với nó. Như sách SQL thần thánh nói: "NULL không thể so sánh trực tiếp với bất cứ thứ gì".

Làm sao cho đúng?

Để kiểm tra giá trị có phải NULL không, hãy dùng IS NULL:

SELECT *
FROM students
WHERE age IS NULL;

Bây giờ bạn sẽ nhận được tất cả sinh viên chưa có tuổi.

Lỗi 2: Hàm tổng hợp bỏ qua NULL (trừ COUNT(*))

Khi chạy truy vấn với hàm tổng hợp, NULL tự động bị loại khỏi phép tính. Điều này có thể dẫn đến kết quả bất ngờ.

Chuyện gì xảy ra?

SELECT AVG(salary) AS avg_salary
FROM employees;

Nếu cột salaryNULL, các dòng đó sẽ bị bỏ qua, và lương trung bình sẽ được tính mà không có những bản ghi đó. Điều này có thể làm bạn hiểu sai về mức lương trung bình.

Làm sao tránh?

Trước khi tổng hợp, hãy chắc chắn bạn thay NULL bằng giá trị mặc định. Ví dụ, dùng COALESCE():

SELECT AVG(COALESCE(salary, 0)) AS avg_salary
FROM employees;

Bây giờ các giá trị NULL sẽ được thay bằng 0 trước khi tính toán.

Lỗi 3: So sánh NULL với nhau

Trong database, NULL không bằng bất cứ thứ gì, kể cả một NULL khác. Điều này có thể làm bạn bất ngờ.

Chuyện gì xảy ra?

SELECT *
FROM students
WHERE NULL = NULL;

Truy vấn này cũng trả về kết quả rỗng. Tại sao? Vì SQL cho rằng sự vắng mặt của một giá trị không thể "bằng" sự vắng mặt của cái khác. Đúng là SQL hơi triết học nhỉ.

Làm sao cho đúng?

Nếu cần kiểm tra hai NULL có "bằng nhau" không, hãy dùng các cú pháp đặc biệt như IS NULL. Ví dụ:

SELECT *
FROM students
WHERE first_name IS NULL AND last_name IS NULL;

Lỗi 4: Chia cho NULL

Chia cho NULL — không chỉ là lỗi, mà còn là kiểu "tội ác toán học" mà SQL sẽ trả về kết quả vô nghĩa — NULL.

Chuyện gì xảy ra?

SELECT 10 / NULL AS result;

Kết quả? NULL. SQL từ chối hiểu bạn muốn gì luôn.

Làm sao tránh?

Để bảo vệ truy vấn khỏi mấy chuyện này, hãy dùng COALESCE() hoặc NULLIF():

SELECT 10 / COALESCE(divisor, 1) AS result
FROM calculations;

Trong truy vấn này, nếu divisorNULL, thay vì chia cho NULL sẽ chia cho 1.

Lỗi 5: Toán tử logic không hoạt động với NULL

NULL phá vỡ logic ngay khi xuất hiện trong biểu thức. Ví dụ, điều kiện TRUE AND NULL trả về NULL, chứ không phải TRUE hay FALSE.

Chuyện gì xảy ra?

SELECT *
FROM students
WHERE age > 18 OR age = NULL;

Trong trường hợp này, dù age > 18 đúng với một số dòng, một số dòng có NULL ở cột age có thể bị loại khỏi kết quả. Tại sao? Vì phần age = NULL sẽ trả về NULL, không phải TRUE.

Làm sao cho đúng?

Luôn xử lý rõ ràng giá trị NULL trong điều kiện logic:

SELECT *
FROM students
WHERE age > 18 OR age IS NULL;

Lỗi 6: Hành vi không rõ ràng khi sắp xếp NULL (lỗi "nặng" nhất)

Nếu truy vấn dùng ORDER BY, hành vi của NULL có thể làm bạn bất ngờ. Mặc định, PostgreSQL sắp xếp dòng có NULL ở cuối khi tăng dần và ở đầu khi giảm dần.

Chuyện gì xảy ra?

SELECT product_name, price
FROM products
ORDER BY price;

Nếu priceNULL, các dòng đó sẽ hiện ở cuối danh sách.

Làm sao tránh bất ngờ?

Bạn có thể chỉ rõ cách sắp xếp NULL bằng NULLS FIRST hoặc NULLS LAST:

SELECT product_name, price
FROM products
ORDER BY price NULLS FIRST;

Lỗi 7: Làm việc sai với khóa ngoại và NULL

Giá trị NULL trong cột khóa ngoại đôi khi dẫn đến hành vi bất ngờ.

Chuyện gì xảy ra?

Nếu bạn thêm khóa ngoại vào bảng và thử chèn dòng mà trường khóa ngoại để trống, PostgreSQL sẽ im lặng luôn. Đó là vì giá trị NULL không được kiểm tra đối chiếu với bảng liên kết.

Làm sao cho đúng?

Dùng ràng buộc NOT NULL nếu muốn loại bỏ khả năng dùng NULL ở các trường này. Hoặc chỉ cần nhớ rằng giá trị NULL sẽ là "trẻ mồ côi", không thuộc về bảng liên kết nào cả.

Chi tiết về bảng liên kết và khóa ngoại bạn sẽ biết ở bài sau :P

1
Khảo sát/đố vui
, cấp độ , bài học
Không có sẵn
Biểu thức điều kiện
Biểu thức điều kiện
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION