CodeGym /Kursy /SQL SELF /Praca z NULL wartościami podczas łączenia d...

Praca z NULL wartościami podczas łączenia danych

SQL SELF
Poziom 12 , Lekcja 0
Dostępny

Wyobraź sobie, że łączysz dwie tabele: students (studenci) i enrollments (zapisy na kursy). Jeśli w tabeli enrollments nie ma info o jakimś studencie, ale używasz np. LEFT JOIN, wiersze z tabeli students i tak się pojawią, ale info z enrollments będzie brakować. Zamiast konkretnych danych w takich przypadkach pojawia się NULL.

Wygląda to mniej więcej tak:

Tabela students:

id name
1 Eva
2 Peter
3 Anna

Tabela enrollments:

student_id course_name
1 Matematyka
1 Informatyka
2 Fizyka

Zapytanie z LEFT JOIN:

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

Wynik:

id name course_name
1 Eva Matematyka
1 Eva Informatyka
2 Peter Fizyka
3 Anna NULL

No hej, NULL! Jak widzisz, dla Anny, która nie jest zapisana na żaden kurs, info o kursie nie istnieje i pojawia się NULL.

Jak NULL wpływa na zapytania?

NULL to nie "zero" i nie "pusty string", to brak wartości. Takie zachowanie ma kilka ciekawych (i czasem wkurzających) konsekwencji:

Porównania z NULL:

Jeśli napiszesz coś w stylu WHERE course_name = NULL, zapytanie nie zwróci wierszy z NULL. Dlaczego? Bo z NULL nie da się porównywać wartości bezpośrednio.

Żeby sprawdzić, czy jest NULL, trzeba użyć specjalnych operatorów:

WHERE course_name IS NULL

Operacje matematyczne:

Każda operacja z NULL zwraca NULL. Na przykład:

SELECT 5 + NULL; -- wynik: NULL

Funkcje agregujące:

Większość funkcji agregujących, takich jak SUM(), AVG(), ignoruje NULL, ale COUNT(*) liczy je jako "istniejące wiersze".

Jak ogarnąć NULL?

  1. Zamiana NULL na czytelne wartości przez COALESCE()

Funkcja COALESCE() pozwala zamienić NULL na inną wartość. Na przykład, jeśli kursu brak, możesz podać "Brak kursu":

SELECT
    students.id, 
    students.name, 
    COALESCE(enrollments.course_name, 'Brak kursu') AS course_name
FROM 
    students LEFT JOIN enrollments 
    ON students.id = enrollments.student_id;

Wynik:

id name course_name
1 Eva Matematyka
1 Eva Informatyka
2 Peter Fizyka
3 Anna Brak kursu

Teraz wygląda to dużo lepiej, prawda?

  1. Filtrowanie NULL wartości

Jeśli nie chcesz widzieć wierszy z NULL, możesz użyć warunku WHERE ... IS NOT NULL. Na przykład:

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;

Wynik:

id name course_name
1 Eva Matematyka
1 Eva Informatyka
2 Peter Fizyka

Anna znika z wyniku, bo nie ma zapisów na kursy.

  1. Liczenie z uwzględnieniem NULL: przykład z COUNT

Jak już wspomniałem, niektóre funkcje ignorują NULL, a niektóre nie. Na przykład:

Żeby policzyć wszystkie wiersze, także te, gdzie jest NULL:

SELECT COUNT(*) FROM students; -- Liczy WSZYSTKIE wiersze (także te, gdzie `course_name` = NULL)

Żeby policzyć tylko wiersze, gdzie nie ma NULL:

SELECT COUNT(course_name) FROM enrollments;
  1. Wyrażenia warunkowe z CASE

Jeśli nie podoba Ci się COALESCE() albo chcesz więcej kontroli, spróbuj użyć CASE. Na przykład:

SELECT
    students.id, 
    students.name,
    CASE
        WHEN enrollments.course_name IS NULL THEN 'Brak kursu'
        ELSE enrollments.course_name
    END AS course_name
FROM 
    students LEFT JOIN enrollments 
    ON students.id = enrollments.student_id;

Wynik będzie taki sam jak przy użyciu COALESCE(), ale CASE pozwala opisać bardziej złożone zasady.

  1. Używaj INNER JOIN, jeśli masz pewność, że nie będzie NULL

Najbardziej radykalny sposób na uniknięcie NULL — po prostu nie dopuszczać do ich pojawienia się, używając INNER JOIN. Ten typ joinów zwraca tylko wiersze z dopasowaniami w obu tabelach:

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

Bez niespodzianek — tylko studenci zapisani na kursy.

Wynik:

id name course_name
1 Eva Matematyka
1 Eva Informatyka
2 Peter Fizyka

Jeśli Twoje dane wymagają pokazania wszystkich wartości, także NULL, INNER JOIN się nie sprawdzi, ale czasem to wszystko, czego potrzebujesz.

Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION