Łączenie wyników dwóch zapytań klauzulą UNION oraz zapisywanie różnicy i części wspólnej zbiorów przy pomocy IN i NOT IN.
Złączenie tabel dokłada kolumny – wynik staje się szerszy. UNION działa w drugą stronę: skleja wyniki dwóch zapytań jeden pod drugim, więc wynik staje się dłuższy. To odpowiednik sumy zbiorów.
Dwa warunki, które muszą być spełnione. Oba łączone zapytania muszą zwracać tę samą liczbę kolumn, a odpowiadające sobie kolumny muszą być tego samego typu. Nazwy kolumn nie muszą się zgadzać – nagłówki wyniku bierze się z pierwszego zapytania.
UNION usuwa duplikaty, tak jak DISTINCT: wiersz występujący w obu zapytaniach pojawi się w wyniku raz. Jeśli powtórzenia mają zostać, służy do tego wariant UNION ALL – dodatkowo szybszy, bo baza nie musi porównywać wierszy między sobą.
Wpisany wprost tekst jako kolumna. Przy UNION bardzo przydaje się możliwość umieszczenia w SELECT napisu, którego nie ma w żadnej tabeli. Dzięki temu można podpisać, z którego zapytania pochodzi dana część wyniku – bez tego dwie liczby jedna pod drugą są nie do odróżnienia. Taki napis, jak każde wyrażenie, wymaga etykiety AS.
Pułapka z sortowaniem. ORDER BY w zapytaniu z UNION odnosi się do całego połączonego wyniku, a nie do poszczególnych części. Próba posortowania osobno każdego członu zwykle nie działa tak, jak się tego oczekuje – i, co gorsza, nie zgłasza błędu. Objawia się to brakiem sortowania tam, gdzie się go spodziewaliśmy. Rozwiązaniem jest ujęcie każdego członu w nawiasy albo przeniesienie go do podzapytania w miejsce tabeli.
Różnica i część wspólna zbiorów. Nie każda baza ma na nie osobne słowa kluczowe, ale obie da się zapisać podzapytaniem:
Różnica – „co jest w pierwszej tabeli, a czego nie ma w drugiej" – to NOT IN z podzapytaniem. Tak odpowiada się na pytanie „którzy uczniowie nie mają ani jednej oceny".
Część wspólna – „co występuje w obu" – to IN z podzapytaniem. Warunek jest ten sam, tylko bez zaprzeczenia.
W obu przypadkach kluczowe jest, żeby kolumna porównywana w WHERE i kolumna zwracana przez podzapytanie opisywały to samo – zwykle jest to klucz łączący obie tabele.
-- Wpisany wprost tekst podpisuje, skąd pochodzi która liczba SELECT 'srednia co najmniej 4,0' AS grupa, COUNT(*) AS ilu FROM uczniowie WHERE srednia >= 4.00 UNION SELECT 'srednia ponizej 4,0' AS grupa, COUNT(*) AS ilu FROM uczniowie WHERE srednia < 4.00
| grupa | ilu |
|---|---|
| srednia co najmniej 4,0 | 3 |
| srednia ponizej 4,0 | 2 |
-- Różnica zbiorów: uczniowie, którzy nie mają ani jednej oceny SELECT nazwisko FROM uczniowie WHERE id NOT IN (SELECT uczen_id FROM oceny)
| nazwisko |
|---|
| Zając |
| Dąbrowski |
-- Część wspólna: uczniowie, którzy mają przynajmniej jedną ocenę SELECT nazwisko FROM uczniowie WHERE id IN (SELECT uczen_id FROM oceny)
| nazwisko |
|---|
| Kowalska |
| Nowak |
| Wiśniewski |
Policz kolumny w obu członach, zanim uruchomisz zapytanie. Niezgodna liczba kolumn to najczęstszy błąd przy UNION – na szczęście zgłaszany od razu, więc łatwy do naprawienia. Groźniejsza jest niezgodność typów, bo komunikat bywa mylący.
Zdecyduj świadomie między UNION a UNION ALL. Jeśli zliczasz coś w rozłącznych grupach, UNION jest bezpieczny. Ale gdy dwie grupy mogą dać identyczny wiersz – na przykład tę samą liczbę – UNION po cichu zredukuje je do jednego i zestawienie będzie niekompletne. To realna pułapka przy zliczeniach.
Sortowanie przy UNION sprawdź na oko. Brak komunikatu o błędzie nie znaczy, że zadziałało. Spójrz na wynik i upewnij się, że kolejność jest ta, o którą prosiło zadanie.
Zapytania. To ważne rozróżnienie: łączone człony mogą pochodzić z tej samej tabeli, różniąc się tylko warunkiem – i właśnie tak najczęściej wygląda zestawienie zbiorcze.
Z pierwszego zapytania. Etykiety nadane w drugim i kolejnych członach są ignorowane, więc nie ma sensu ich powtarzać – choć nie zaszkodzi, jeśli poprawiają czytelność zapisu.
Tak, kolejne UNION dopisuje się jedno po drugim. Wszystkie muszą spełniać te same warunki co do liczby i typów kolumn.
Zagadnienia z tego samego obszaru matury – warto je powtórzyć razem: