CodeGym /Các khóa học /SQL SELF /Làm việc với NULL khi kết hợp dữ liệu

Làm việc với NULL khi kết hợp dữ liệu

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

Hãy tưởng tượng bạn đang join hai bảng: students (sinh viên) và enrollments (đăng ký khóa học). Nếu trong bảng enrollments không có thông tin về một sinh viên nào đó, nhưng bạn dùng, ví dụ, LEFT JOIN, thì dòng từ bảng students vẫn sẽ xuất hiện, nhưng thông tin từ enrollments sẽ bị thiếu. Thay vì dữ liệu cụ thể, lúc này sẽ xuất hiện NULL.

Đại khái nó sẽ như thế này:

Bảng students:

id name
1 Eva
2 Peter
3 Anna

Bảng enrollments:

student_id course_name
1 Toán học
1 Tin học
2 Vật lý

Câu truy vấn với LEFT JOIN:

SELECT students.id, students.name, enrollments.course_name
FROM students
LEFT JOIN enrollments ON students.id = enrollments.student_id;

Kết quả:

id name course_name
1 Eva Toán học
1 Eva Tin học
2 Peter Vật lý
3 Anna NULL

Chào mừng NULL nhé! Như bạn thấy, với Anna, người không đăng ký bất kỳ khóa học nào, thông tin về khóa học bị thiếu và thay vào đó là NULL.

NULL ảnh hưởng đến truy vấn như thế nào?

NULL — không phải là "số 0" cũng không phải là "chuỗi rỗng", nó là không có giá trị. Kiểu này dẫn đến một số hậu quả thú vị (và đôi khi khá khó chịu):

So sánh với NULL:

Nếu bạn viết kiểu như WHERE course_name = NULL, truy vấn sẽ không trả về dòng nào có NULL. Tại sao? Vì không thể so sánh trực tiếp với NULL.

Để kiểm tra có NULL hay không, phải dùng toán tử đặc biệt:

WHERE course_name IS NULL

Phép toán toán học:

Bất kỳ phép toán nào với NULL đều trả về NULL. Ví dụ:

SELECT 5 + NULL; -- kết quả: NULL

Hàm tổng hợp:

Hầu hết các hàm tổng hợp như SUM(), AVG() sẽ bỏ qua NULL, nhưng COUNT(*) thì vẫn đếm chúng như là "dòng tồn tại".

Làm sao xử lý NULL?

  1. Thay NULL bằng giá trị dễ hiểu với COALESCE()

Hàm COALESCE() cho phép thay NULL bằng giá trị khác. Ví dụ, nếu không có khóa học, bạn có thể ghi "Không có khóa học":

SELECT
    students.id, 
    students.name, 
    COALESCE(enrollments.course_name, 'Không có khóa học') AS course_name
FROM 
    students LEFT JOIN enrollments 
    ON students.id = enrollments.student_id;

Kết quả:

id name course_name
1 Eva Toán học
1 Eva Tin học
2 Peter Vật lý
3 Anna Không có khóa học

Nhìn ổn hơn nhiều rồi đúng không?

  1. Lọc bỏ các giá trị NULL

Nếu bạn không muốn thấy dòng có NULL, hãy dùng điều kiện WHERE ... IS NOT NULL. Ví dụ:

SELECT
    students.id, 
    students.name, 
    enrollments.course_name
FROM 
    students LEFT JOIN enrollments 
    ON students.id = enrollments.student_id
WHERE 
    enrollments.course_name IS NOT NULL;

Kết quả:

id name course_name
1 Eva Toán học
1 Eva Tin học
2 Peter Vật lý

Anna biến mất khỏi kết quả vì cô ấy không có đăng ký khóa học nào.

  1. Đếm có xét đến NULL: ví dụ với COUNT

Như đã nói ở trên, một số hàm sẽ bỏ qua NULL, một số thì không. Ví dụ:

Để đếm tất cả các dòng, kể cả dòng có NULL:

SELECT COUNT(*) FROM students; -- Đếm TẤT CẢ các dòng (kể cả dòng có `course_name` = NULL)

Để đếm chỉ các dòng không có NULL:

SELECT COUNT(course_name) FROM enrollments;
  1. Biểu thức điều kiện với CASE

Nếu bạn không thích COALESCE() hoặc muốn linh hoạt hơn, hãy thử dùng CASE. Ví dụ:

SELECT
    students.id, 
    students.name,
    CASE
        WHEN enrollments.course_name IS NULL THEN 'Không có khóa học'
        ELSE enrollments.course_name
    END AS course_name
FROM 
    students LEFT JOIN enrollments 
    ON students.id = enrollments.student_id;

Kết quả sẽ giống như khi dùng COALESCE(), nhưng CASE cho phép bạn viết quy tắc phức tạp hơn.

  1. Dùng INNER JOIN nếu chắc chắn không có NULL

Cách triệt để nhất để tránh NULL là không cho nó xuất hiện, dùng INNER JOIN. Kiểu join này chỉ trả về dòng có dữ liệu ở cả hai bảng:

SELECT
    students.id, 
    students.name, 
    enrollments.course_name
FROM 
    students INNER JOIN enrollments 
    ON students.id = enrollments.student_id;

Không có bất ngờ gì — chỉ những sinh viên đã đăng ký khóa học mới xuất hiện.

Kết quả:

id name course_name
1 Eva Toán học
1 Eva Tin học
2 Peter Vật lý

Nếu dữ liệu của bạn cần hiển thị tất cả giá trị, kể cả NULL, thì INNER JOIN không phù hợp, nhưng đôi khi vậy là đủ rồi.

Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION