KWALIFIKACJA INF3 - STYCZEŃ 2016

PYTANIE NR 21.
Zdefiniowano bazę danych z tabelą mieszkańcy o polach: nazwisko, imie, miasto. Następnie stworzono następujące zapytanie do bazy:
SELECT nazwisko, imie FROM mieszkańcy WHERE miasto='Poznań' UNION ALL SELECT nazwisko, imie FROM mieszkańcy WHERE miasto='Kraków';

Wskaż zapytanie, które zwróci identyczne dane.
A.
B.
C.
D.
Wyjaśnienie poprawnej odpowiedzi:
Zapytanie z UNION ALL łączy wyniki dwóch SELECT-ów i nie usuwa duplikatów. Gdy oba SELECT-y pobierają te same kolumny z tej samej tabeli i różnią się tylko warunkiem miasta, równoważny efekt daje pojedynczy SELECT z warunkiem w WHERE: miasto='Poznań' OR miasto='Kraków'.

Pełne wyjaśnienie:

W podanym przykładzie wykonano dwa niezależne zapytania do tej samej tabeli mieszkańcy:

  • pierwsze wybiera osoby, dla których miasto='Poznań',
  • drugie wybiera osoby, dla których miasto='Kraków'.

Następnie wyniki są połączone operatorem UNION ALL. Kluczowe jest słowo ALL: oznacza, że SQL nie usuwa duplikatów między częściami składowymi. Innymi słowy, wynik końcowy to "doklejenie" jednego zbioru wierszy pod drugi.

Jeżeli oba SELECT-y:

  • pobierają te same kolumny (nazwisko, imie),
  • pochodzą z tej samej tabeli,
  • różnią się wyłącznie warunkiem w klauzuli WHERE,

to można je zapisać jako jedno zapytanie, łącząc warunki operatorem logicznym OR:

SELECT nazwisko, imie
FROM mieszkańcy
WHERE miasto='Poznań' OR miasto='Kraków';

To zapytanie zwraca wszystkie wiersze spełniające którykolwiek z warunków, czyli dokładnie te same rekordy, które w wersji z UNION ALL trafiają do wyniku z pierwszej lub z drugiej części.

Dlaczego pozostałe propozycje są błędne:

  • HAVING służy do filtrowania wyników po agregacji (zwykle z GROUP BY), a nie do porównania pojedynczej kolumny z literałami w podanej formie; dodatkowo składnia "miasto HAVING 'Poznań'" jest niepoprawna.
  • Użycie AS do aliasowania tabeli nie zastępuje warunku filtrowania; zapis z "'Poznań' OR 'Kraków'" nie tworzy sensownego kryterium wierszy.
  • BETWEEN wymaga zakresu (dolna i górna granica) i ma inną składnię; nie zapisuje się go jako "BETWEEN 'Poznań' OR 'Kraków'". Nawet poprawne BETWEEN dla tekstu oznaczałoby porządek leksykograficzny, a nie "jedno z dwóch miast".

Wskazówka egzaminacyjna: gdy widzisz dwa SELECT-y z tej samej tabeli różniące się tylko prostym warunkiem, często da się je scalić przez OR (albo przez IN (...)), zachowując znaczenie wyniku.

Dodatkowe pytania

Dodatkowe pytania (FAQ):
UNION ALL łączy wyniki dwóch zapytań, zachowując wszystkie wiersze, także duplikaty. UNION robi to samo, ale usuwa duplikaty (zwykle wymaga dodatkowego przetwarzania). Gdy zależy Ci na identycznym wyniku "doklejania" rekordów, używaj UNION ALL.
Jeśli oba SELECT-y pobierają te same kolumny z tej samej tabeli i różnią się tylko warunkiem, scalisz je przez OR w WHERE, np. kolumna='A' OR kolumna='B'. Alternatywnie często stosuje się IN ('A','B').
Bo oba SELECT-y filtrują tę samą tabelę po tej samej kolumnie, tylko na dwie wartości. W WHERE z OR wybierasz wiersze spełniające dowolny z tych warunków, czyli dokładnie te, które trafiłyby do wyniku z pierwszej albo z drugiej części UNION ALL.
Tak, logicznie to często równoważne: miasto IN ('Poznań','Kraków') oznacza "miasto równe jednej z wartości". Na egzaminie wybór zależy od odpowiedzi w wariantach, ale warto rozpoznawać oba zapisy jako poprawne formy filtrowania.
Różnice pojawiają się, gdy SELECT-y nie są symetryczne: pobierają inne kolumny, mają różne JOIN-y, różne warunki dodatkowe albo dodają stałe wartości w SELECT. Wtedy scalenie przez OR może zmienić liczbę lub strukturę wierszy w wyniku.
WHERE filtruje pojedyncze wiersze przed grupowaniem. HAVING filtruje dopiero wyniki po agregacji (np. po GROUP BY). Stosowanie HAVING bez agregacji albo w złej składni to częsty błąd, bo "brzmi podobnie" do warunku.
BETWEEN wymaga dwóch granic zakresu w postaci BETWEEN A AND B, a nie operatora OR. Dodatkowo BETWEEN dla tekstu oznacza zakres leksykograficzny, a nie "jedno z dwóch miast". Do dwóch wartości użyj OR albo IN.
Najczęściej myli się UNION z UNION ALL (duplikaty), nie zauważa się, że oba SELECT-y dotyczą tej samej tabeli i tych samych kolumn, albo wybiera się odpowiedź z "ładnie wyglądającym" słowem kluczowym (HAVING/BETWEEN) mimo błędnej składni.
Sam UNION ALL nie gwarantuje kolejności wyników. Kolejność jest pewna dopiero po użyciu ORDER BY w zapytaniu zewnętrznym (dla całego wyniku). W praktyce bazy mogą zwracać wiersze w "jakiejś" kolejności, ale nie należy na tym polegać.
Ćwicz na realnej bazie: twórz tabelę, wstaw kilka rekordów (także duplikaty) i porównuj wyniki: OR vs IN vs UNION vs UNION ALL. Zwracaj uwagę na to, czy zapytania pobierają te same kolumny i czy filtrują tę samą tabelę—to zwykle klucz do rozpoznania równoważności.
info

To pytanie poprawnie rozwiązuje 57% zdających egzamin. średnie

Eksperci podkreślają: "Zapytanie z UNION ALL łączy wyniki dwóch SELECT-ów i nie usuwa duplikatów."

Źródła:

  • PostgreSQL Documentation: "UNION, INTERSECT, and EXCEPT" (set operations) – https://www.postgresql.org/docs/current/queries-union.html (dostęp 2026-02-18)
  • MySQL 8.0 Reference Manual: "UNION Clause" – https://dev.mysql.com/doc/refman/8.0/en/union.html (dostęp 2026-02-18)
  • SQLite Documentation: "Compound SELECT Statements" (UNION/UNION ALL) – https://www.sqlite.org/lang_select.html#compound_select_statements (dostęp 2026-02-18)

Materiały:

  • Dokumentacja wybranego dialektu SQL (np. MySQL lub PostgreSQL) – sekcje: SELECT, WHERE, UNION/UNION ALL
  • Ćwiczenia praktyczne: porównywanie wyników zapytań OR vs UNION ALL na danych z duplikatami
  • Materiały kursowe z baz danych dla kwalifikacji dotyczącej aplikacji i baz danych (część SQL – filtrowanie i łączenie wyników)

Aktualizacja pytania: 31.03.2026



Aktualizacja pytania: 31.03.2026
📡 Brak połączenia internetowego