SELECT to podstawowa instrukcja języka SQL - pobiera dane z bazy. Pełny szkielet: SELECT (które kolumny), FROM + JOIN (z których tabel), WHERE (filtr wierszy), GROUP BY (grupowanie), HAVING (filtr grup), ORDER BY (sortowanie), LIMIT (ile wierszy). Dla analityka to brama do samodzielności: zamiast czekać trzy dni na wyciąg z IT, sam zadaje pytanie bazie.
Rzecz, którą warto zrozumieć od razu: kolejność logicznego wykonania różni się od kolejności zapisu. Baza najpierw bierze tabele (FROM/JOIN), potem filtruje wiersze (WHERE), grupuje (GROUP BY), filtruje grupy (HAVING), dopiero wtedy wybiera kolumny (SELECT) i sortuje (ORDER BY). Stąd m.in. to, że w WHERE nie można użyć aliasu zdefiniowanego w SELECT.
Przykład (MediFlow). Pytanie dyrektorki: które placówki najlepiej przyjęły rejestrację online w maju?
SELECT p.nazwa, COUNT(*) AS wizyty_online
FROM wizyty w
JOIN placowki p ON p.id = w.placowka_id
WHERE w.kanal = 'online'
AND w.data_wizyty >= '2026-05-01'
AND w.data_wizyty < '2026-06-01'
GROUP BY p.nazwa
ORDER BY wizyty_online DESC;
Dwanaście wierszy wyniku, a w nich od razu anomalia: placówka Ursynów ma trzy razy mniej rezerwacji online niż porównywalne - punkt wyjścia do następnego pytania, nie koniec analizy.
Częsta pomyłka. Mylenie WHERE z HAVING: WHERE filtruje pojedyncze wiersze przed grupowaniem, HAVING - wyniki po agregacji ("pokaż placówki z ponad 200 wizytami" to HAVING). Druga: SELECT * na dużych tabelach produkcyjnych - ciągnie wszystkie kolumny, obciąża bazę i psuje czytelność. Trzecia: brak warunku złączenia w JOIN, czyli iloczyn kartezjański - 40 tys. wizyt × 12 placówek daje prawie pół miliona bezsensownych wierszy i wynik, który wygląda wiarygodnie, dopóki ktoś nie sprawdzi sumy.