Na tabeli dania, której wiersze zostały pokazane poniżej, wykonano przedstawioną kwerendę: SELECT * FROM dania WHERE typ < 3 AND cena < 30 LIMIT 5;
Ile wierszy wybierze ta kwerenda?
| id | typ | nazwa | cena |
|---|---|---|---|
| 1 | 1 | Gazpacho | 20 |
| 2 | 1 | Krem z warzyw | 25 |
| 3 | 1 | Gulaszowa ostra | 30 |
| 4 | 2 | Kaczka i owoc | 30 |
| 5 | 2 | Kurczak pieczony | 40 |
| 6 | 3 | wierzbowy przysmak | 35 |
| 7 | 2 | Mintał w panierce | 30 |
| 8 | 2 | Alle kotlet | 30 |
| 9 | 3 | Owoce morza | 20 |
| 10 | 3 | Grzybki, warzywka, sos | 15 |
| 11 | 3 | Orzechy i chipsy | 10 |
| 12 | 3 | Tatar i jajo | 15 |
| 13 | 3 | Bukiet warzyw | 10 |
Poprawna odpowiedź to 2, ponieważ kwerenda wybiera tylko te rekordy, które spełniają jednocześnie oba warunki z klauzuli WHERE: typ < 3 oraz cena < 30. Operator AND oznacza, że nie wystarczy spełnić jednego warunku, muszą być prawdziwe oba naraz. W tej tabeli typ < 3 mają dania o typie 1 lub 2. Następnie trzeba jeszcze sprawdzić cenę: ma być mniejsza niż 30, czyli cena równa 30 już odpada. Pasują więc tylko rekordy: id 1, Gazpacho, cena 20 oraz id 2, Krem z warzyw, cena 25. Rekordy z ceną 30 nie spełniają warunku cena < 30, bo znak < jest ostry, bez równości. LIMIT 5 nie oznacza, że baza zawsze zwróci 5 wierszy, tylko że może zwrócić maksymalnie 5 pasujących wierszy. Jeżeli pasują tylko 2, wynik będzie miał właśnie 2 rekordy. W praktyce to bardzo ważne przy filtrowaniu danych, np. w menu restauracji, sklepie internetowym albo panelu administracyjnym. Moim zdaniem najczęstszy haczyk tutaj to właśnie pomylenie < z <=. Dobra praktyka w SQL to czytać warunek etapami: najpierw filtr WHERE, potem dopiero ograniczenie liczby wyników przez LIMIT.
W tej kwerendzie łatwo się pomylić, bo na pierwszy rzut oka widać kilka rekordów z typem 1 lub 2 i można odruchowo policzyć ich więcej. Trzeba jednak pamiętać, że warunek po WHERE działa jak filtr logiczny. Zapis typ < 3 AND cena < 30 oznacza przecięcie dwóch zbiorów danych, a nie ich sumę. Czyli rekord musi mieć typ mniejszy od 3 oraz cenę mniejszą od 30 w tym samym czasie. Sam typ 1 albo 2 jeszcze nie wystarcza, jeśli cena wynosi 30 lub 40. Tak samo sama niska cena nie wystarcza, jeśli typ wynosi 3, bo typ 3 nie jest mniejszy od 3. To jest typowy błąd myślowy przy operatorze AND: ktoś sprawdza jeden warunek, a drugi traktuje trochę jak dodatek. W SQL oba warunki są równorzędne i muszą przejść pozytywnie. Innym częstym źródłem złej odpowiedzi jest interpretacja LIMIT 5. LIMIT nie dobiera brakujących rekordów do pięciu i nie ignoruje warunku WHERE. On tylko ucina wynik, jeśli pasujących rekordów byłoby więcej niż 5. Jeżeli po filtrowaniu zostają 2 wiersze, to LIMIT 5 nic już nie zmienia. Odpowiedź 5 wynika zwykle z myślenia, że LIMIT zawsze narzuca liczbę zwracanych rekordów, a tak nie jest. Wyniki 8 lub 13 mogą brać się z policzenia zbyt szerokiego zakresu danych, na przykład wszystkich rekordów z ceną poniżej albo równą 30, albo nawet całej tabeli. W bazach danych takie drobiazgi są ważne, bo znak < różni się od <=, a AND różni się od OR. Z mojego doświadczenia najlepiej przy takich zadaniach przejść po wierszach tabeli i przy każdym zapytać: czy typ jest mniejszy od 3? czy cena jest mniejsza od 30? Dopiero dwa razy „tak” daje rekord w wyniku.