Znak % w SQL pojawia się głównie przy dopasowywaniu wzorców tekstowych i decyduje o tym, czy zapytanie zwróci prefiksy, fragmenty napisów albo wszystkie niepuste wartości pasujące do reguły. W tym artykule pokazuję, jak działa z operatorem LIKE, kiedy trzeba go traktować jako znak dosłowny, czym różni się od _ oraz dlaczego wpływa także na wydajność. To praktyczna rzecz, którą warto rozumieć, zanim zaczniesz filtrować nazwy, adresy, komentarze czy inne dane tekstowe.
Najważniejsze zasady użycia procenta w filtrach SQL
-
% w
LIKEoznacza dowolny ciąg znaków, także pusty. -
LIKE 'A%'szuka wartości zaczynających się od litery A, aLIKE '%sql%'wartości zawierających wskazany fragment. -
_odpowiada dokładnie jednemu znakowi, więc rozwiązuje inny problem niż procent. - Aby znaleźć dosłowny znak
%, trzeba go uciec przezESCAPEalbo użyć składni właściwej dla danego silnika bazy danych. - Wzorce z
%na początku zwykle gorzej korzystają z indeksów niż dopasowanie prefiksu.
Co naprawdę oznacza znak procenta w SQL
W praktyce traktuję % jako wildcard, czyli symbol zastępujący dowolny fragment tekstu. W połączeniu z LIKE oznacza to dopasowanie od zera do wielu znaków, więc wzorzec nie musi mieć z góry znanej długości ani konkretnej końcówki. To dlatego LIKE 'A%' zwraca wartości zaczynające się od A, a LIKE '%a%' znajduje teksty zawierające literę a w dowolnym miejscu.
Najważniejsze jest jednak to, że LIKE nie działa jak luźne „szukaj gdziekolwiek”, tylko jak pełne porównanie wzorca z całym ciągiem. Jeśli chcesz znaleźć fragment wewnątrz tekstu, musisz świadomie dodać procent z lewej i prawej strony. Ja zwykle tłumaczę to tak: bez % masz dopasowanie dokładne, z jednym procentem filtrujesz początek albo koniec, a z dwoma procentami szukasz środka.
| Wzorzec | Znaczenie | Praktyczny efekt |
|---|---|---|
LIKE 'A%' |
Tekst zaczyna się od A | Dobry filtr dla nazw, kodów i prefiksów |
LIKE '%sql%' |
Tekst zawiera wskazany fragment | Wyszukiwanie słowa lub jego części w środku zdania |
LIKE '%' |
Dowolny tekst | Zwraca wszystkie nie-NULL wartości tekstowe |
LIKE 'A_' |
A i dokładnie jeden dodatkowy znak | Przydatne przy krótkich kodach i skrótach |
Warto zapamiętać jeszcze jeden szczegół: NULL nie zachowuje się jak zwykły tekst. Nawet jeśli wzorzec wygląda na bardzo szeroki, to rekordy z wartością NULL nie przejdą przez porównanie tak, jakby były pustym napisem. Po opanowaniu tej podstawy łatwo przejść do budowania wzorców pod konkretne scenariusze.
Jak budować wzorce, które zwracają dokładnie to, czego szukasz
Najbardziej praktyczne użycie procenta sprowadza się do trzech scenariuszy: wyszukiwania po prefiksie, po sufiksie i po fragmencie środka tekstu. Ja najczęściej zaczynam właśnie od prefiksu, bo to rozwiązanie najbardziej przewidywalne i zwykle najlepiej współpracuje z indeksami. Dopiero gdy to nie wystarcza, sięgam po wzorce z procentem na początku lub po obu stronach.
| Scenariusz | Przykład | Kiedy ma sens |
|---|---|---|
| Prefiks | WHERE city LIKE 'War%' |
Gdy chcesz znaleźć miasta, nazwy lub kody zaczynające się od danego ciągu |
| Sufiks | WHERE file_name LIKE '%.pdf' |
Gdy końcówka jest ważniejsza niż początek tekstu |
| Środek tekstu | WHERE description LIKE '%python%' |
Gdy szukasz słowa lub frazy ukrytej w dłuższym opisie |
| Jeden znak | WHERE sku LIKE 'A_12' |
Gdy jeden element jest nieznany, ale jego długość jest stała |
SELECT id, name
FROM users
WHERE name LIKE 'Jan%';Ten prosty przykład pokazuje, dlaczego % jest tak użyteczny: nie musisz znać całego ciągu, żeby zawęzić wyniki do sensownego zakresu. Jeśli jednak w danych występuje sam znak procenta jako część wartości, trzeba go potraktować jak zwykły znak, a nie wildcard. To prowadzi do jednego z najczęstszych problemów w codziennej pracy z tekstem.
Jak dopasować dosłowny znak procenta
Gdy chcesz znaleźć sam symbol %, musisz go uciec. Najbardziej przenośnym rozwiązaniem jest ESCAPE, bo pozwala jasno wskazać znak pomocniczy, który mówi bazie: „następny symbol potraktuj dosłownie”. W praktyce lubię używać prostego znaku, na przykład ! albo #, bo wzorzec staje się czytelniejszy niż przy bardziej „egzotycznych” escape'ach.
SELECT id, notes
FROM products
WHERE notes LIKE '%30!%%' ESCAPE '!';W tym przykładzie pierwsze % nadal oznacza dowolny ciąg znaków, ale sekwencja !% mówi: szukaj literalnego procenta. Dzięki temu zapytanie znajdzie wpisy zawierające na przykład 30%, a nie wartości zaczynające się od 30 i dowolnych dalszych znaków. W niektórych silnikach spotkasz też składnię specyficzną dla producenta, ale jeśli zależy Ci na przenośności, ESCAPE jest bezpieczniejszym wyborem.
Gdy wzorzec jest już poprawny składniowo, pojawia się kolejne pytanie: czy takie zapytanie będzie działało sprawnie na większej tabeli.
Dlaczego ustawienie wzorca wpływa na wydajność
Najkrócej: pozycja procenta ma znaczenie dla indeksów. Jeśli wzorzec zaczyna się od konkretnego ciągu, baza często może skorzystać z indeksu b-tree i zawęzić przeszukiwanie. Jeśli jednak wzorzec zaczyna się od %, silnik zwykle musi sprawdzić dużo większą część danych, a czasem całą kolumnę.
| Wzorzec | Typowe zachowanie | Co to oznacza w praktyce |
|---|---|---|
'abc%' |
Często możliwe użycie indeksu | Dobre rozwiązanie dla prefiksów i autouzupełniania |
'%abc' |
Zwykle bez korzyści z klasycznego indeksu | Przeszukiwanie końcówek bywa droższe |
'%abc%' |
Najczęściej pełniejszy skan danych | Wyszukiwanie fragmentów w środku tekstu jest najcięższe |
Jeśli takie filtrowanie ma działać często i na dużej tabeli, sam LIKE może nie wystarczyć. Wtedy sensownie rozważyć wyszukiwanie pełnotekstowe, indeksy trigramowe albo inny model przeszukiwania dopasowany do typu danych. Ja zwykle traktuję LIKE '%...%' jako wygodne narzędzie do prostych przypadków, a nie uniwersalny zamiennik wyszukiwarki tekstu. Po wydajności zostają jeszcze pułapki, które potrafią zaskoczyć nawet wtedy, gdy zapytanie wygląda poprawnie.
Najczęstsze pułapki przy pracy z LIKE
Najwięcej błędów widzę w czterech miejscach: w założeniach o NULL, w czułości na wielkość liter, w myleniu % z _ i w oczekiwaniu, że każde wyszukiwanie będzie szybkie. To nie są drobne niuanse, tylko rzeczy, które realnie zmieniają wynik zapytania albo jego koszt wykonania.
- NULL nie jest tekstem i nie zachowuje się jak pusty łańcuch.
- Czułość na wielkość liter zależy od silnika i kolacji, więc to samo zapytanie może działać inaczej w PostgreSQL, MySQL i SQL Server.
-
%i_rozwiązują różne problemy: pierwszy oznacza dowolny ciąg znaków, drugi dokładnie jeden znak. - Wzorzec z procentem na początku często jest dużo droższy niż dopasowanie prefiksu.
- Literalny procent trzeba uciec, inaczej baza potraktuje go jak wildcard.
W PostgreSQL, jeśli chcesz ignorować wielkość liter, zwykle sięgasz po ILIKE; w MySQL i SQL Server częściej decyduje kolacja bazy albo kolumny. To ważne, bo identyczny wzorzec może zwrócić inne wyniki zależnie od środowiska. Z tego powodu przy zapytaniach przenośnych zawsze sprawdzam nie tylko sam operator, ale też ustawienia porównywania tekstu.
Po tych pułapkach zostaje już tylko praktyka wdrożeniowa: jak ja podchodzę do procenta, kiedy zapytanie ma po prostu działać dobrze, a nie tylko „przechodzić” w edytorze.
Co biorę z tego praktycznie przy codziennych zapytaniach
Jeśli miałbym zostawić tylko kilka zasad, byłyby bardzo proste. Używaj procenta wtedy, gdy naprawdę potrzebujesz wzorca, a nie domyślnego „luźnego” porównania. Wybieraj prefiks, jeśli możesz, bo to zwykle najtańsza i najbardziej przewidywalna forma filtrowania. A gdy musisz szukać środka tekstu, licz się z tym, że baza może wykonać znacznie cięższą pracę.
- Do dopasowania początku tekstu używaj wzorca w stylu
'abc%'. - Do wyszukiwania fragmentu wewnątrz tekstu używaj
'%abc%', ale tylko wtedy, gdy to naprawdę potrzebne. - Gdy szukasz dosłownego
%, dodajESCAPEalbo użyj składni właściwej dla konkretnego silnika. - Nie zakładaj, że czułość na wielkość liter będzie taka sama w każdej bazie danych.
- Przy dużych tabelach sprawdzaj plan zapytania, zamiast zgadywać, czy filtr jest tani.
Jeżeli zapamiętasz tylko jedną rzecz, niech będzie nią to, że % nie jest ozdobnikiem, tylko częścią reguły dopasowania. W SQL ten jeden znak potrafi zmienić wynik zapytania, sposób korzystania z indeksu i końcowy koszt wykonania, więc warto używać go świadomie, a nie „na wyczucie”.
