W poprzednich lekcjach pokazałem Ci jak wykonywać podstawowe zapytania do bazy danych. Poznałeś składnie instrukcji SELECT i jej podstawowe możliwości. W tej części Darmowego Kursu SQL przyjrzymy się bliżej filtrowaniu danych, czyli wybieraniu konkretnych wierszy według zadanych kryteriów. Poznasz operatory SQL, które pozwolą bardzo precyzyjnie dostać się do informacji których potrzebujesz!
Jeżeli nie widziałeś jeszcze wpisu rozpoczynającego Darmowy Kurs SQL koniecznie zajrzyj tutaj: Kurs SQL #01: Wprowadzenie i środowisko
Porównywanie wartości
Klauzula WHERE może wykorzystywać różne operatory do porównywania wartości. Praktycznie każdy z nich znasz z lekcji matematyki w podstawówce 😉 Zobaczmy na przykładach co robią poszczególne operatory.
Operator <>
Operator <> pozwala na wyszukiwanie wierszy przetrzymujących wartość inną niż podana. Można go stosować wymiennie z operatorem !=. Obydwa robią dokładnie to samo 🙂
select
prod_id, cust_id, channel_id, promo_id, quantity_sold, amount_sold
from sh.sales
where channel_id <> 3;
PROD_ID | CUST_ID | CHANNEL_ID | PROMO_ID | QUANTITY_SOLD | AMOUNT_SOLD |
---|---|---|---|---|---|
13 | 524 | 2 | 999 | 1 | 1205.99 |
14 | 205 | 4 | 999 | 1 | 1108.99 |
14 | 228 | 4 | 999 | 1 | 1108.99 |
14 | 5378 | 4 | 999 | 1 | 1108.99 |
Powyższe zapytanie zwraca nam kilka kolumn z tabeli SALES, znajdującej się w schemacie SH. Wybierane są tylko wiersze dotyczące sprzedaży wykonanych z kanałów innych, niż ten o CHANNEL_ID równym 3. W wyniku tego zapytania znajdziesz zatem wiersze o CHANNEL_ID równym 1, 2 lub 4, ale ani jednego z CHANNEL_ID ustawionym na 3.
Operatory < i >
Skoro można szukać wartości innych niż podana, powinno się także dać wybrać wartości mniejsze lub większe niż podana wartość. Jak się już pewnie domyślasz tutaj sprawdzi się operator < lub operator >.
select
prod_id, cust_id, channel_id, promo_id, quantity_sold, amount_sold
from sh.sales
where amount_sold > 1100;
PROD_ID | CUST_ID | CHANNEL_ID | PROMO_ID | QUANTITY_SOLD | AMOUNT_SOLD |
---|---|---|---|---|---|
13 | 987 | 3 | 999 | 1 | 1232.16 |
13 | 1660 | 3 | 999 | 1 | 1232.16 |
13 | 1762 | 3 | 999 | 1 | 1232.16 |
13 | 1843 | 3 | 999 | 1 | 1232.16 |
Tym razem szukamy sobie informacji o sprzedażach w których uzyskana była kwota sprzedaży większa niż 1100. Analogicznie możemy poszukać nieco mniej dochodowych sprzedaży, np. takich które przyniosły mniej niż 1100 przychodu.
select
prod_id, cust_id, channel_id, promo_id, quantity_sold, amount_sold
from sh.sales
where amount_sold < 1100;
PROD_ID | CUST_ID | CHANNEL_ID | PROMO_ID | QUANTITY_SOLD | AMOUNT_SOLD |
---|---|---|---|---|---|
15 | 3718 | 3 | 999 | 1 | 1013.99 |
15 | 33763 | 3 | 999 | 1 | 1013.99 |
15 | 1104 | 4 | 999 | 1 | 1013.99 |
15 | 205 | 3 | 999 | 1 | 999.99 |
Powyższe operatory pokazują wartości większe niż podana wartość. Warto pamiętać też że można wykorzystywać operatory „większe/mniejsze równe”. Zapis tego typu operatorów jest dosyć oczywisty <= i >=.
Konfiguracja Oracle Live SQL
Domyślnie środowisko Oracle Live SQL wyświetla jedynie pierwsze 50 wyników wykonanego zapytania. Zachowanie to warto zmodyfikować, aby tego dokonać na górze po prawej stronie wybierz Actions –> Maximum Rows Preference. W oknie które się pojawi wybierz wartość 500 lub wyższą(najlepiej maksymalną) i zatwierdź wybór guzikiem Apply Changes.
Operatory ANY i ALL
Nieco mniej oczywiste są operatory ANY i ALL. Pierwszy z nich ANY służy do porównania wartości z którąkolwiek z listy. Przez słowem kluczowym ANY należy użyć jednego z poznanych wcześniej operatorów.
select
prod_id, cust_id, channel_id, promo_id, quantity_sold
from sh.sales
where channel_id > ANY (1,2,3);
PROD_ID | CUST_ID | CHANNEL_ID | PROMO_ID | QUANTITY_SOLD |
14 | 12123 | 3 | 999 | 1 |
14 | 2266 | 2 | 999 | 1 |
14 | 12655 | 2 | 999 | 1 |
14 | 305 | 4 | 999 | 1 |
14 | 1658 | 4 | 999 | 1 |
Zapytanie zwraca wiersze opisujące sprzedaże z numerem CHANNEL_ID większym niż którykolwiek z elementów listy. Na liście zawarłem liczby 1, 2 i 3, dlatego też w wynikach możemy spodziewać się wszystkich wierszy oprócz tych z CHANNEL_ID równym 1. Zobaczmy co się stanie, gdy zastosujemy operator ALL.
select
prod_id, cust_id, channel_id, promo_id, quantity_sold
from sh.sales
where channel_id > ALL (1,2,3);
PROD_ID | CUST_ID | CHANNEL_ID | PROMO_ID | QUANTITY_SOLD | AMOUNT_SOLD |
---|---|---|---|---|---|
14 | 205 | 4 | 999 | 1 | 1108.99 |
14 | 228 | 4 | 999 | 1 | 1108.99 |
14 | 5378 | 4 | 999 | 1 | 1108.99 |
14 | 2994 | 4 | 999 | 1 | 1265.03 |
Tym razem zapytanie pokazuje wiersze dla CHANNEL_ID większego niż każdy z elementów podanej listy. Można zatem powiedzieć, że zapytanie wyświetli wiersze z CHANNEL_ID większym niż największy element z listy – w naszym przypadku największa jest liczba 3.
Pewnie zadajesz sobie pytanie do czego używane są operatory ALL i ANY. Dostrzeżesz jak bardzo wartościowe są kiedy poznasz zapytania zagnieżdżone. Wspomnę tylko… zamiast listy „1,2,3” można wstawić kolejny SELECT! Ale do tego dojdziemy w kolejnych lekcjach 😉
Poznaj SQL z przyjaznymi wykładami video – przejdź kompleksowy kurs: Kurs SQL w Praktyce!
Operatory SQL
Operatory SQL służą do ograniczania liczby zwróconych wierszy poprzez dopasowywanie do wzorców, list wartości, zakresów wartości lub wartości NULL.
Operator LIKE
Do tej pory pracowaliśmy głownie z kolumnami zawierającymi w sobie wartości liczbowe. Czas przyjąć jako wartości dla operatora ciągi znakowe. Operator LIKE pozwala na sprawne wyszukiwanie wierszy posiadających w kolumnie tekst pasujący do podane wzorca. Przetestujmy to!
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_last_name like 'B%';
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
---|---|---|---|
37009 | Ada | Baley | 1925 |
40564 | Ada | Baley | 1974 |
44119 | Ada | Baley | 1975 |
34392 | Ada | Baley | 1978 |
Powyższe zapytanie filtruje wyniki po wartościach w kolumnie CUST_LAST_NAME, przechowywującej nazwiska. Zastosowanie operatora LIKE, pozwoliło na wyszukanie wszystkich klientów których nazwisko zaczyna się od litery B. Procent w wzorcu oznacza dowolny ciąg znaków, krótko mówiąc interesują nasz wiersze które w kolumnie CUST_LAST_NAME mają wartości zaczynające się do litery B dowolnych znaków po niej.
Spróbujmy zatem jeszcze zastosować znak procenta w kilku miejscach wzorca.
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_last_name like '%ov%';
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
---|---|---|---|
38789 | Angie | Grover | 1964 |
42344 | Angie | Grover | 1942 |
16636 | Angie | Grover | 1965 |
46122 | Angie | Grover | 1981 |
Jak widzisz tym razem szukam wierszy które w CUST_LAST_NAME mają ciąg znaków zaczynający się od dowolnych znaków, następnie występuje w nich 'ov’, po którym mogą być znów dowolne znaki.
Oprócz znaku procenta w wzorcach można również wykorzystać znak podreślenia '_’. Będzie oznaczał on pojedynczy dowolny znak.
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_last_name like '_b%';
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
---|---|---|---|
37051 | Bee | Abbey | 1976 |
40606 | Bee | Abbey | 1964 |
44161 | Bee | Abbey | 1942 |
34814 | Bee | Abbey | 1973 |
Wzorzec z powyższego zapytanie wyszukuje wartości w których literę b poprzedza tylko jeden dowolny znak. Za literą b mogą występować dowolne znaki. Taki wzorzec wyszuka np. nazwisko Abbey.
Operator taki jak LIKE posiadać będzie także swoje przeciwieństwo(negacje) w postaci operatora NOT LIKE. Operator NOT LIKE będzie zawsze wszystkie te wiersze których operator LIKE z danym wzorcem nie wyświetliłby.
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_last_name not like '_b%';
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
---|---|---|---|
49671 | Abigail | Ruddy | 1976 |
3228 | Abigail | Ruddy | 1964 |
6783 | Abigail | Ruddy | 1942 |
10338 | Abigail | Ruddy | 1977 |
Jak widać powyższe zapytanie wyświetliło te wiersze które dla kolumny CUST_LAST_NAME nie pasują do podanego wzorca 😉
Operator IN
Kolejnym z operatorów jest IN. Służy on do wyświetlania wierszy których wartość w kolumnie pokrywa się z którymś z elementów podanej listy. Działa on zarówno z tekstem jak i liczbami.
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_year_of_birth in (1964, 1976, 1978);
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
101821 | Boriana | Farrell | 1964 |
49671 | Abigail | Ruddy | 1976 |
16562 | Abner | Rossellett | 1976 |
13558 | Garnett | Pilcher | 1978 |
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_first_name in ('Ada','Abel');
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
36115 | Abel | Aaron | 1936 |
39670 | Abel | Aaron | 1953 |
14787 | Ada | Nenninger | 1938 |
18342 | Ada | Nenninger | 1958 |
W ramach ćwiczenia przetestuj samodzielnie operator NOT IN 😉
Operator BETWEEN
Do tej pory poznawane przez Nas operatory SQL przyjmowały konkretną wartość(opcjonalnie listę wartości) do porównania. Kolejny z nich będzie pozwalał definiować przedział z którego chcemy pozyskać wiersze.
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_id between 1 and 100;
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
---|---|---|---|
1 | Abigail | Kessel | 1946 |
2 | Anne | Koch | 1957 |
3 | Buick | Emmerson | 1939 |
4 | Frank | Hardy | 1934 |
Powyższe zapytanie zwróci klientów których CUST_ID jest w przedziale od 1 do 100. Warto zauważyć że mówimy tu o przedziale domkniętym – wartości 1 i 100 także są zawarte w wyniku zapytania. Analogicznie jak w poprzednich operatorach tak i tutaj możemy wykorzystywać też operator NOT BETWEEN.
Operatory logiczne
Świetnym dopełnieniem tematu operatorów są operatory logiczne. Pozwalają one na tworzenie bardziej zaawansowanych filtrów wyszukiwania, łączących po kilka warunków.
Operator AND
Operator AND pozwoli nam na wyszukiwanie wierszy dla których wszystkie z wymienionych warunków są prawdziwe.
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_id < 100 and cust_first_name like 'A%';
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
---|---|---|---|
1 | Abigail | Kessel | 1946 |
2 | Anne | Koch | 1957 |
17 | Alyce | Reagan | 1957 |
51 | Alyce | Gray | 1959 |
Powyższe zapytanie wyświetli nam klientów których CUST_ID jest mniejsze niż 100, a ich imię zaczyna się od litery A.
Operator OR
Operator OR pozwoli nam kolei na pozyskanie wierszy których przynajmniej jeden z warunków jest spełniony. Inaczej mówiąc spełniony jest warunek pierwszy LUB drugi.
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where cust_id < 100 or cust_first_name like 'A%';
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
---|---|---|---|
49671 | Abigail | Ruddy | 1976 |
3228 | Abigail | Ruddy | 1964 |
6783 | Abigail | Ruddy | 1942 |
10338 | Abigail | Ruddy | 1977 |
Jak widzisz w poprzednim zapytaniu zmieniłem jedynie AND na OR. Wynik uległ diametralnej zmianie. Otrzymaliśmy spis klientów których CUST_ID jest mniejsze od 100 LUB imię zaczyna się od litery A 🙂
Łączenie Operatorów
Operatory SQL można łączyć na różne sposoby. W przypadku AND o OR, zawsze operator AND jest rozpatrywany jako pierwszy. Operatory porównania zawsze mają pierwszeństwo przed AND.
select
cust_id, cust_first_name, cust_last_name, cust_year_of_birth
from sh.customers
where
cust_id < 100
or cust_first_name like 'A%'
and cust_year_of_birth = 1976;
CUST_ID | CUST_FIRST_NAME | CUST_LAST_NAME | CUST_YEAR_OF_BIRTH |
---|---|---|---|
49671 | Abigail | Ruddy | 1976 |
16562 | Abner | Rossellett | 1976 |
35226 | Abel | Walsh | 1976 |
1 | Abigail | Kessel | 1946 |
Tutaj ćwiczenie dla Ciebie, przeanalizuj co robi powyższe zapytanie i opisz w komentarzu pod postem które z warunków mają pierwszeństwo przed którymi(wynikające z zasad którymi kierują się operatory SQL) 😉
Czwarta część kursu już dostępna! Kurs SQL #04: Sortowanie wierszy – klauzula ORDER BY