Poprawne jest zapytanie: DELETE FROM pracownicy WHERE pensja BETWEEN 500 AND 1000 AND miejsce_pracy LIKE '%tx%';. Słowo kluczowe BETWEEN w SQL oznacza przedział domknięty, czyli w tym przypadku usuwani będą pracownicy, którzy zarabiają co najmniej 500 i jednocześnie nie więcej niż 1000 zł. To dokładnie odpowiada treści zadania, bez żadnych niedomówień na granicach zakresu. Gdybyśmy użyli > i <, to wartości 500 i 1000 zostałyby wykluczone, co w tym zadaniu byłoby niezgodne z wymaganiem. Drugi warunek korzysta z operatora LIKE wraz z maską '%tx%'. Wzorzec z procentami z obu stron oznacza: znajdź wszystkie wiersze, gdzie ciąg znaków „tx” występuje gdziekolwiek w tekście kolumny miejsce_pracy – na początku, w środku albo na końcu. W MySQL znak % jest standardowym symbolem wieloznacznym (wildcard) dla dowolnego ciągu znaków, a nie gwiazdka *, dlatego zapis z % jest poprawny i zgodny z dokumentacją. Spójnik AND jest tu kluczowy, bo warunek mówi wyraźnie: usuwamy tylko tych pracowników, którzy spełniają jednocześnie oba kryteria – zarówno zakres pensji, jak i fragment tekstu w miejscu pracy. W praktyce takie zapytanie stosuje się np. przy porządkowaniu danych testowych: można szybko usunąć sztuczne rekordy z określonego przedziału płac i z wybranych lokalizacji. Moim zdaniem warto wyrabiać sobie nawyk bardzo precyzyjnego formułowania warunków logicznych (AND/OR) i zawsze sprawdzać, czy zakres jest domknięty czy otwarty. Dobrą praktyką jest też najpierw wykonać SELECT z tym samym WHERE, zobaczyć jakie rekordy zostaną naruszone, a dopiero potem odpalać DELETE – szczególnie na produkcyjnej bazie, bo tam pomyłki bywają bolesne.
W tym zadaniu widać kilka typowych pułapek związanych z SQL-em: składnią operatora LIKE, doborem zakresu liczbowego oraz użyciem spójników logicznych AND i OR. Zacznijmy od wzorca tekstowego. W MySQL, zgodnie ze standardową składnią SQL, do dopasowań wzorców używa się znaków % i _. Procent oznacza dowolny ciąg znaków, a podkreślnik pojedynczy znak. Natomiast gwiazdka * nie jest prawidłowym wildcardem w operatorze LIKE, więc zapis typu LIKE '*tx*' po prostu nie zadziała tak, jak większość osób intuicyjnie zakłada. To jest częsty błąd u osób, które mieszają składnię SQL z np. wyrażeniami w stylu systemów plików czy niektórych narzędzi linuksowych. Kolejna sprawa to warunki logiczne. W tym poleceniu chodziło o wybranie rekordów, które spełniają oba kryteria jednocześnie: pensja w określonym przedziale i miejsce pracy zawiera „tx”. Użycie operatora OR całkowicie zmienia znaczenie zapytania, bo wtedy wystarczy, że spełniony jest tylko jeden z warunków. W efekcie można by usunąć osoby, które mają odpowiednią pensję, ale w ogóle nie mają „tx” w miejscu pracy, albo odwrotnie – mają „tx” w miejscu pracy, ale zarabiają dużo mniej lub więcej niż zadany zakres. To klasyczny przykład nieprecyzyjnie dobranego spójnika logicznego, który na produkcyjnej bazie może zakończyć się masowym usunięciem nie tych danych, co trzeba. Trzeci problem dotyczy interpretacji zakresu. Operator IN z wartościami (500,1000) nie wybiera przedziału od 500 do 1000, tylko dokładnie dwie wartości: 500 i 1000. To nie ma nic wspólnego z „między 500 a 1000”, więc zadanie nie byłoby zrealizowane. Z drugiej strony użycie warunku pensja > 500 AND pensja < 1000 wyklucza wartości graniczne, czyli 500 i 1000, co jest sprzeczne z opisem „nie mniej niż 500 i nie więcej niż 1000”. Z mojego doświadczenia najczęściej takie błędy wynikają z pośpiechu i nieprzeczytania dokładnie treści zadania. Dobra praktyka jest taka, żeby zawsze świadomie decydować, czy zakres ma być domknięty (BETWEEN) czy otwarty (>, <) oraz żeby testować zapytanie w wersji SELECT przed wykonaniem operacji DELETE albo UPDATE. To pozwala od razu zauważyć, że warunki logiczne albo wzorzec LIKE nie działają tak, jak zakładaliśmy w głowie.