Filtrowanie danych

Tworząc zapytania, stajemy ciągle przed problemem maksymalnego ograniczenia wyników tylko do tych co nas interesują. W poprzednim rozdziale (o pobieraniu danych z bazy) przedstawiłem klauzule where, którą chciałbym teraz dokładniej omówić.

Wspomniana klauzula pozwala nam definiować operacje logiczne które muszą zostać spełnione by zobaczyć jakiś wiersz w wynikach. Posłużę się tutaj przykładem z tabelą o przyjaciołach którą omawiałem w poprzedniej części kursu.

select * from przyjaciele where plec=1

jest to najprostsza metoda filtrowania. Wybieramy jedna kolumnę i porównujemy jej wartość z oczekiwaną. Warto zdawać sobie świadomość na których polach w bazie są założone indeksy i filtrować zapytania właśnie po tych polach. Jeśli użytkownik tworzący nie jest świadomy indeksów, nie ma się czym martwić. Napisane pytania na pewno zadziałają, jednak możliwe że będą wymagały optymalizacji. Prawdopodobieństwo potrzeby optymalizacji wzrasta wraz z wielkością tabeli i ilością warunków filtrowania oraz z ilością złączeń. Metody optymalizacji zostaną omówione później. Jednak na wiele prostych rzeczy jest zwracana uwaga ad hoc.

Czasem jednak chcemy zdefiniować więcej warunków, używamy do tego celu słów or lub and.

select * from przyjaciele where (plec=0 and kolor=1) or (plec=1 and kolor=10)

Jak widać w poprzednim przykładzie złączyliśmy 2 warunki ze sobą.

(plec=0 and kolor=1) – oznacza iż 2 zawarte tu warunki muszą być prawdą jednocześnie
() or () – oznacza iż jeden z warunków musi być prawdą.

Przykładowe zapytanie możemy rozumieć tak: Pokaż przyjaciół którzy
są kobietami i mają kolor=1 lub facetów z kolorem 10. Przy tworzeniu takich zapytań warto się zastanowić nad prawdopodobieństwem takiego warunku.
jeśli warunkujemy za pomocą and porównując dwa warunki to należy je ustawić w takiej kolejności by pierwszym warunkiem był ten który ma najniższą szansę zaistnienia. Skoro oba warunki muszą być spełnione, i pierwszy warunek jest fałszem to drugi nie jest sprawdzany. Taki sposób rozumowania nazywa się leniwym. W przypadku warunków OR musimy postąpić odwrotnie. Tylko jeden z warunków musi być prawdą więc należy je zapisać w kolejności od najprawdopodobniejszego

Czasem zachodzi potrzeba pobrania niezbyt zdefiniowanych danych. Np chcielibyśmy poznać wszystkich przyjaciół na literę A. Do tego został utworzony konstrukt like.

select imie from przyjaciele where imie like 'A%'

znaki nam nieznane zastępujemy znakiem %.
Jeśli znamy ilość znaków a nie znamy po prostu zawartości (np szukając 4 literowych imion na A)

select * from przyjaciele where imie like 'A___'

stosujemy jeden podkreślnik (_) na jeden znak.

Oczywiście możemy tworzyć różne konstrukty:
like ‘a__%’
like ‘_a__v_%’
like ‘%’
like ‘_%’ itd

Dośc istotna uwaga:
select * from przyjaciele where imie like 'A'
jest równe
select * from przyjaciele where imie='A'

możemy też tworzyć filtry na operacjach arytmetycznych:

select * from przyjaciele where zarobki > 1000

select * from przyjaciele where (zarobki/5) * zarobki < 10000

itd. Oczywiście możemy zestawiać ze sobą różne rodzaje filtrów

select * from przyjaciele where (((zarobki/5) * zarobki < 10000) and plec=1) or ((zarobki/5) * zarobki > 10000)

Istnieje także filtr between który pobiera wartości z pomiędzy przedziału. Należy jednak uważać przy jego stosowaniu ponieważ każda baza (RDBMS) inaczej definuje granice przedziałów.

select * from przyjaciele where zarobki between 1000 and 2000

jak przy poprzednich przykładach taki filtr możemy łączyć z innymi. Warto jednak between objać nawiasami w celu zwiększenia czytelności.

Istnieje także konstrukt pozwalający wybierać nam ze zbioru wartości:

select * from przyjaciele where kolor in ( 2,4,6)

i jest to tym samym co:

select * from przyjaciele where kolor=2 or kolor=4 or kolor=6

z tą różnicą że IN jest dużo bardziej wydajne.

W filtrze możemy zamieścić także operacje case when i wykorzystywać różne funkcje np:

select * from przyjaciele where floor(zarobki) > 1000

Jeśli by utworzyć tabele z kolegami która zawierała by także identyfikator przyjaciela

to można by używać podzapytań do filtrowania

select * from koledzy where id_przyjaciela in (select id from przyjaciele)

jeśli jesteśmy pewni że podzapytanie zwróci jeden wynik możemy:

select * from koledzy where id_przyjaciela = (select id from przyjaciele where id=10)

I tak możemy sobie generować podzapytania co najmniej 255 razy(dla każdego podzapytania można definiować kolejne.

możemy także pobierając dane z bazy posługiwać się podzapytaniami

select imie,(select k.id from koledzy k where k.id_przyjaciela = p.id) from przyjaciele p where plec=0

Nie jest to może optymalne zapytanie ale pokazuje możliwość. Powyższe nazywa się zapytaniem skorelowanym.
Przedstawia ono złączenie z podzapytaniem. literki k i p to aliasy dla tabel. Oczywiście takie podzapytanie musi zwrócić dokładnie jeden wiersz dla każdego wiersza z zapytania głównego wyjątkiem jest brak wyniku który zostanie przedstawiony jako null.

Jak już wspominamy o wartości null która cechuje się swoimi własnymi prawami. To przyrównywanie do null nie jest dobrym pomysłem:

select * from przyjaciele where kolor = null

nie zadziała poprawnie ( w niektórych RDBMS być może zwróci oczekiwane wyniki, ale nie można na tym zapisie polegać)

poprawny zapis to:

select * from przyjaciele where kolor is null

jeśli chcemy wartości niepuste:

select * from przyjaciele where kolor is not null

Leave a Reply

Your email address will not be published. Required fields are marked *

fourteen + 7 =