W tabeli produkt znajdują się przedmioty wyprodukowane po roku 2000, opisane polami nazwa i rok_produkcji. Przedstawione zapytanie SQL wyświetli listę przedmiotów wyprodukowanych
SELECT * FROM `produkt` WHERE SUBSTR(rok_produkcji, 3, 2) <> 17;
A. w roku 2017
B. w latach innych niż 2017
C. po roku 2017
D. przed rokiem 2017
W tym zapytaniu kluczowe jest zrozumienie działania funkcji SUBSTR oraz operatora <>. Funkcja SUBSTR(rok_produkcji, 3, 2) pobiera z wartości pola rok_produkcji dwa znaki, zaczynając od trzeciego znaku. Dla roku 2017 zapis traktowany tekstowo wygląda jak '2017', więc od trzeciej pozycji dostajemy '17'. Warunek SUBSTR(rok_produkcji, 3, 2) <> 17 oznacza: pokaż tylko te rekordy, dla których pobrany fragment nie jest równy 17. Czyli rekord z rokiem 2017 nie przejdzie warunku, a np. 2005, 2016, 2018 czy 2022 już tak. Dlatego zapytanie wyświetli przedmioty wyprodukowane w latach innych niż 2017. Moim zdaniem warto tu zauważyć jedną rzecz praktyczną: takie filtrowanie po fragmencie roku jest trochę kombinowane. W dobrej praktyce bazodanowej, jeżeli rok_produkcji jest liczbą, prościej i czytelniej byłoby napisać WHERE rok_produkcji <> 2017. Taki zapis jest łatwiejszy w utrzymaniu, bardziej jednoznaczny i zwykle lepszy pod kątem indeksów w bazie danych.
Błąd w tym zadaniu zwykle bierze się z pochopnego odczytania operatora <> albo z potraktowania funkcji SUBSTR tak, jakby porównywała cały rok. Operator <> w SQL oznacza nierówność, czyli „różne od”, a nie „większe od” ani „mniejsze od”. Gdy ktoś wybiera interpretację „po roku 2017”, to najczęściej myli <> z operatorem >. W tym zapytaniu nie ma warunku rok_produkcji > 2017, więc baza nie wybiera tylko rekordów z lat 2018, 2019 itd. Rok 2005 też spełni warunek, bo fragment '05' nie jest równy 17. Podobnie odpowiedź „przed rokiem 2017” wynikałaby z pomylenia <> z <, ale w zapytaniu nie ma sprawdzania, czy rok jest mniejszy od 2017. Rok 2020 również spełnia ten warunek, bo jego końcówka to '20'. Niepoprawne jest też stwierdzenie, że zapytanie pokaże rok 2017, ponieważ dla wartości 2017 funkcja SUBSTR pobierze fragment '17', a porównanie '17' <> 17 będzie fałszywe. W praktyce SQL, szczególnie w MySQL, tekst '17' może zostać porównany z liczbą 17 przez konwersję typu, więc efekt jest taki, że rekordy z 2017 są odrzucane. Z mojego doświadczenia to dobry przykład, że trzeba czytać warunek WHERE bardzo dokładnie: najpierw funkcja przetwarza dane, potem dopiero operator logiczny decyduje, czy rekord zostanie pokazany.