Instrukcja SELECT w SQL

Słownik kwalifikacji INF.03 - Tworzenie i administrowanie stronami i aplikacjami internetowymi oraz bazami danych

SELECT służy do pobierania danych z tabeli w bazie danych. Jest to jedna z najczęściej używanych instrukcji języka SQL (Structured Query Language). Pozwala wskazać, które kolumny mają zostać zwrócone, z której tabeli oraz na jakich warunkach.

Infografika przedstawiająca działanie instrukcji SELECT w SQL: po lewej tabela źródłowa pracownicy z 5 wierszami, pośrodku zapytanie SELECT imie, nazwisko FROM pracownicy WHERE pensja > 4500, po prawej tabela wynikowa z 3 wierszami.

W algebrze relacji odpowiada operacjom selekcji (wybór wierszy spełniających warunek) i projekcji (wybór kolumn).

Podstawowa składnia

SELECT kolumna1, kolumna2
FROM nazwa_tabeli;

Jeżeli chcemy pobrać wszystkie kolumny, można użyć znaku *:

SELECT *
FROM sklepy;

Pełna kolejność elementów zapytania SELECT (najczęściej spotykana na egzaminie):

SELECT [DISTINCT] kolumny
FROM tabela
WHERE warunek
GROUP BY kolumna
HAVING warunek_grupowy
ORDER BY kolumna [ASC | DESC]
LIMIT liczba;

Tej kolejności nie wolno zmieniać - SQL wymaga, by elementy zapytania występowały w określonym porządku.

Klauzula WHERE - filtrowanie wierszy

WHERE ogranicza wynik do wierszy spełniających podany warunek. Najczęściej spotykane operatory:

OperatorZnaczeniePrzykład
=równeWHERE miasto = 'Wrocław'
<> lub !=różneWHERE wiek <> 18
>, <, >=, <=większe, mniejszeWHERE wiek >= 26
ANDjednocześnieWHERE miasto = 'Wrocław' AND branza = 'spożywczy'
ORalboWHERE miasto = 'Wrocław' OR miasto = 'Kraków'
IN (...)wartość z listyWHERE wiek IN (18, 30)
BETWEEN ... AND ...z zakresuWHERE wiek BETWEEN 18 AND 30
LIKEdopasowanie wzorcaWHERE imie LIKE 'A%'
IS NULLwartość pustaWHERE adres IS NULL

Uwaga - IN nie oznacza "od ... do ...": WHERE wiek IN (18, 30) zwróci tylko wiersze, w których wiek wynosi dokładnie 18 lub dokładnie 30, a nie wszystkie wartości pomiędzy. Aby pobrać wartości z zakresu, należy użyć BETWEEN.

Przykłady WHERE

-- Tylko sklepy spożywcze we Wrocławiu
SELECT nazwa
FROM sklepy
WHERE miasto = 'Wrocław' AND branza = 'spożywczy';

-- Pracownicy, którzy ukończyli 26 lat
SELECT *
FROM pracownicy
WHERE wiek >= 26;

-- Pamięci RAM produkcji Kingston
SELECT model
FROM podzespoly
WHERE typ = 'RAM' AND producent = 'Kingston';

Klauzula ORDER BY - sortowanie

ORDER BY sortuje wynik według wskazanej kolumny:

  • ASC - rosnąco (domyślnie),
  • DESC - malejąco.
-- Sortowanie uczniów według daty urodzenia rosnąco
SELECT *
FROM uczniowie
ORDER BY data_urodzenia ASC;

-- Sortowanie produktów według ceny malejąco
SELECT nazwa, cena
FROM produkty
ORDER BY cena DESC;

Klauzula DISTINCT - unikalne wartości

DISTINCT usuwa duplikaty z wyniku zapytania. Pozostają tylko różne (unikalne) wartości:

-- Lista miast, w których są sklepy (każde miasto raz)
SELECT DISTINCT miasto
FROM sklepy;

-- Ilu różnych wykonawców jest w tabeli muzyka
SELECT COUNT(DISTINCT wykonawca)
FROM muzyka;

Bez DISTINCT zapytanie zwróciłoby tyle wierszy, ile jest w tabeli (z powtórzeniami).

Funkcje agregujące

Funkcje agregujące wykonują obliczenia na zbiorze wierszy i zwracają jedną wartość:

FunkcjaZastosowanie
COUNT(*)liczba wszystkich wierszy w tabeli
COUNT(kolumna)liczba wierszy, w których kolumna nie jest NULL
COUNT(DISTINCT kolumna)liczba unikalnych wartości w kolumnie
SUM(kolumna)suma wartości
AVG(kolumna)średnia arytmetyczna
MIN(kolumna)wartość najmniejsza
MAX(kolumna)wartość największa

Przykłady:

-- Średnia pensja wszystkich pracowników
SELECT AVG(pensja)
FROM pracownicy;

-- Liczba wszystkich wierszy w tabeli Koty
SELECT COUNT(*)
FROM Koty;

-- Najwyższe i najniższe wynagrodzenie
SELECT MAX(pensja), MIN(pensja)
FROM pracownicy;

Klauzula GROUP BY - grupowanie

GROUP BY grupuje wiersze według wartości w wybranej kolumnie. Najczęściej używana razem z funkcjami agregującymi - pozwala obliczyć agregat osobno dla każdej grupy:

-- Średnia pensja osobno dla kobiet i mężczyzn
SELECT plec, AVG(zarobek)
FROM pracownicy
GROUP BY plec;

-- Liczba sklepów w każdym mieście
SELECT miasto, COUNT(*)
FROM sklepy
GROUP BY miasto;

-- Łączny obrót dla każdej grupy cenowej
SELECT grupa_cenowa, SUM(obrot)
FROM sprzedaz
GROUP BY grupa_cenowa;

Aby filtrować same grupy (a nie pojedyncze wiersze), używa się klauzuli HAVING:

-- Miasta, w których jest więcej niż 5 sklepów
SELECT miasto, COUNT(*)
FROM sklepy
GROUP BY miasto
HAVING COUNT(*) > 5;

Różnica WHERE vs HAVING:
- WHERE filtruje pojedyncze wiersze przed grupowaniem,
- HAVING filtruje grupy po zastosowaniu GROUP BY.

Funkcja CONCAT - łączenie tekstów

Funkcja CONCAT łączy (skleja) kilka napisów w jeden:

-- Wyświetlenie pełnego imienia i nazwiska w jednej kolumnie
SELECT CONCAT(imie, ' ', nazwisko) AS pelne_imie
FROM pracownicy;

Wynik: Anna Kowalska, Jan Nowak, itd. Bez CONCAT imię i nazwisko byłyby w osobnych kolumnach.

Aliasy kolumn (AS)

Słowo kluczowe AS pozwala nadać kolumnie inną nazwę w wyniku zapytania:

SELECT pensja * 12 AS pensja_roczna
FROM pracownicy;

W wyniku kolumna z obliczoną wartością nazywa się pensja_roczna, a nie pensja * 12.

Operacje na zbiorach wyników

SQL pozwala łączyć wyniki kilku zapytań SELECT za pomocą operatorów zbiorów:

  • UNION - suma wyników (bez duplikatów),
  • UNION ALL - suma wyników (z duplikatami),
  • INTERSECT - część wspólna - tylko wiersze, które występują w obu zapytaniach,
  • EXCEPT (lub MINUS) - różnica - wiersze z pierwszego zapytania, których nie ma w drugim.
-- Klienci, którzy kupili produkt A I produkt B
SELECT klient_id FROM zamowienia WHERE produkt = 'A'
INTERSECT
SELECT klient_id FROM zamowienia WHERE produkt = 'B';

Uprawnienia GRANT i REVOKE

W SQL nie tylko pobiera się dane, ale też zarządza uprawnieniami do ich pobierania. Służą do tego instrukcje:

  • GRANT - nadaje uprawnienia użytkownikowi,
  • REVOKE - odbiera uprawnienia użytkownikowi.

Prawo SELECT oznacza, że użytkownik może odczytywać dane z tabeli.

-- Nadanie prawa SELECT do wszystkich tabel w bazie hurtownia
GRANT SELECT ON hurtownia.* TO 'sprzedawca'@'localhost';

-- Odebranie prawa SELECT do tabeli klienci użytkownikowi jan
REVOKE SELECT ON klienci FROM 'jan';

W pytaniach egzaminacyjnych pojawiają się też inne uprawnienia: INSERT, UPDATE, DELETE, ALL PRIVILEGES.

Selekcja, projekcja, łączenie - algebra relacji

W teorii baz danych operacje na tabelach opisuje się w języku algebry relacji:

  • Selekcja - wybór wierszy spełniających warunek (odpowiednik WHERE w SQL),
  • Projekcja - wybór kolumn (odpowiednik listy kolumn w SELECT),
  • Złączenie (join) - połączenie wierszy z różnych tabel (odpowiednik JOIN w SQL).

Pytania egzaminacyjne czasem pytają wprost: "W algebrze relacji działanie selekcji polega na..." - chodzi wtedy o wybór wierszy, nie kolumn.

Pełen przykład - hurtownia

Załóżmy tabelę sprzedaz z polami: id, kontrahent, grupa_cenowa, obrot.

-- 1. Tylko kontrahenci z drugiej grupy cenowej, posortowani po obrocie malejąco
SELECT kontrahent, obrot
FROM sprzedaz
WHERE grupa_cenowa = 2
ORDER BY obrot DESC;

-- 2. Suma obrotu w każdej grupie cenowej
SELECT grupa_cenowa, SUM(obrot)
FROM sprzedaz
GROUP BY grupa_cenowa;

-- 3. Liczba różnych kontrahentów w bazie
SELECT COUNT(DISTINCT kontrahent)
FROM sprzedaz;

-- 4. Grupy cenowe z łącznym obrotem powyżej 10 000
SELECT grupa_cenowa, SUM(obrot)
FROM sprzedaz
GROUP BY grupa_cenowa
HAVING SUM(obrot) > 10000;

Typowe błędy

Mylenie nazwy tabeli z nazwą kolumny:

SELECT sklepy FROM nazwa;   -- ŹLE
SELECT nazwa FROM sklepy;   -- DOBRZE

Po SELECT podaje się kolumny, po FROM nazwę tabeli.

Mylenie IN z BETWEEN:

WHERE wiek IN (18, 30)         -- tylko wiek = 18 lub wiek = 30
WHERE wiek BETWEEN 18 AND 30   -- każdy wiek od 18 do 30

Złe miejsce HAVING:

SELECT plec, AVG(zarobek) FROM pracownicy HAVING zarobek > 5000   -- ŹLE
SELECT plec, AVG(zarobek) FROM pracownicy WHERE zarobek > 5000 GROUP BY plec   -- DOBRZE

HAVING filtruje grupy po GROUP BY, do filtrowania pojedynczych wierszy używa się WHERE.

Brak GROUP BY przy agregacji z dodatkową kolumną:

SELECT plec, AVG(zarobek) FROM pracownicy;   -- ŹLE (brak GROUP BY)
SELECT plec, AVG(zarobek) FROM pracownicy GROUP BY plec;   -- DOBRZE

Najczęstsze pytania egzaminacyjne o SELECT

Jak pobrać wszystkie kolumny z tabeli?
Używając gwiazdki: SELECT * FROM tabela;

Jak obliczyć średnią wartość z kolumny?
Używając funkcji agregującej AVG: SELECT AVG(kolumna) FROM tabela;

Jak policzyć wszystkie wiersze tabeli?
Używając COUNT(*): SELECT COUNT(*) FROM tabela;

Co robi DISTINCT?
Zwraca tylko unikalne (różne) wartości, eliminując duplikaty.

Co robi INTERSECT?
Zwraca wiersze, które występują jednocześnie w obu połączonych zapytaniach (część wspólna).

Co oznacza prawo SELECT w poleceniu GRANT?
Pozwala użytkownikowi bazy danych odczytywać dane z tabeli.

Co robi REVOKE SELECT ON tabela FROM user?
Odbiera użytkownikowi prawo do odczytu danych z tabeli.

Czym różni się WHERE od HAVING?
WHERE filtruje pojedyncze wiersze przed grupowaniem, HAVING filtruje całe grupy po zastosowaniu GROUP BY.

Co to selekcja w algebrze relacji?
Wybór wierszy tabeli spełniających warunek (odpowiednik WHERE w SQL).

Jak posortować wynik zapytania?
Klauzulą ORDER BY kolumna [ASC|DESC].

Co zapamiętać na egzamin?

  • SELECT służy do pobierania danych z tabeli.
  • Kolejność klauzul: SELECTFROMWHEREGROUP BYHAVINGORDER BY.
  • Po SELECT podaje się kolumny, po FROM - tabelę.
  • Funkcje agregujące: COUNT, SUM, AVG, MIN, MAX.
  • DISTINCT = unikalne wartości (bez duplikatów).
  • GROUP BY grupuje wiersze, HAVING filtruje grupy.
  • INBETWEEN: IN to lista wartości, BETWEEN to zakres.
  • INTERSECT = część wspólna dwóch zapytań.
  • GRANT SELECT nadaje prawo do odczytu, REVOKE SELECT je odbiera.
  • W algebrze relacji selekcja = wybór wierszy, projekcja = wybór kolumn.
  • CONCAT łączy teksty z różnych kolumn.