UNION czy UNION ALL? Jak wybrać właściwy operator SQL

Jeremi Andrzejewski • 4 października 2026
Porównanie SQL UNION vs UNION ALL: UNION usuwa duplikaty, UNION ALL zachowuje wszystkie wiersze, w tym powtórzenia.

Spis treści

Gdy łączysz wyniki kilku zapytań SQL, wybór między UNION a UNION ALL wpływa nie tylko na liczbę rekordów, lecz także na czas wykonania całej operacji. Porównanie union vs union all pokazuje, kiedy usuwać powtórzenia, kiedy zachować każdy wiersz oraz jak uniknąć typowych błędów z typami danych, kolejnością kolumn i sortowaniem.

Najważniejsza decyzja zależy od tego, czy duplikaty są danymi, czy problemem

  • UNION łączy wyniki i usuwa identyczne wiersze.
  • UNION ALL zachowuje wszystkie rekordy, także powtórzenia.
  • Obie części zapytania muszą zwracać taką samą liczbę kolumn w zgodnej kolejności.
  • UNION ALL zwykle działa szybciej, bo nie wymaga deduplikacji.
  • Jeśli powtórzenia mają znaczenie biznesowe, użycie zwykłego UNION może zafałszować wynik.

Jak działają UNION i UNION ALL

Oba operatory ustawiają wyniki zapytań jeden pod drugim. Nie dopasowują rekordów po wspólnym kluczu, więc działają inaczej niż JOIN, który łączy kolumny z powiązanych tabel w tym samym wierszu.

SELECT email
FROM klienci_2025

UNION

SELECT email
FROM klienci_2026;

W tym przykładzie otrzymasz jedną kolumnę z adresami e-mail z obu tabel. Jeśli ten sam adres występuje w obu źródłach, UNION pokaże go tylko raz. Operator wykonuje więc działanie podobne do połączenia zbiorów, w którym powtarzające się elementy są redukowane.

SELECT email
FROM klienci_2025

UNION ALL

SELECT email
FROM klienci_2026;

Wersja z dopiskiem ALL zachowa każdy rekord. Jeżeli adres pojawi się dwa razy w pierwszej tabeli i trzy razy w drugiej, wynik będzie zawierał pięć wierszy. To często właściwe zachowanie przy raportowaniu sprzedaży, analizie logów lub łączeniu tabel partycjonowanych według miesięcy.

Cecha UNION UNION ALL
Duplikaty Usuwa identyczne wiersze Zachowuje wszystkie wiersze
Wydajność Zwykle niższa przy dużych wynikach Zwykle wyższa
Zastosowanie Lista unikalnych wartości Pełny zbiór danych i poprawne liczenie rekordów
Ryzyko Może usunąć potrzebne rekordy Może zwrócić powtórzenia, których nie zauważysz

Warunki poprawnego łączenia zapytań

Każde zapytanie połączone operatorem zbiorów musi zwracać tyle samo kolumn. Kolumny na tych samych pozycjach powinny mieć zgodne albo możliwe do konwersji typy danych.

SELECT id, nazwa
FROM produkty

UNION ALL

SELECT kod, opis
FROM uslugi;

To zapytanie może być poprawne, jeśli id i kod są typami liczbowymi, a nazwa i opis tekstem. Nazwy kolumn w wyniku pochodzą zazwyczaj z pierwszego SELECT-a, dlatego dobrze nadać im czytelne aliasy właśnie w pierwszej części.

SELECT id AS element_id, nazwa AS element_nazwa
FROM produkty

UNION ALL

SELECT kod, opis
FROM uslugi;

Nie musisz pobierać tych samych nazw kolumn, ale musisz zachować ich sensowny układ. Gdy jedno źródło nie ma danej informacji, użyj wartości NULL albo stałej z odpowiednim typem.

SELECT id, nazwa, cena, 'produkt' AS typ
FROM produkty

UNION ALL

SELECT id, nazwa, NULL AS cena, 'usługa' AS typ
FROM uslugi;

Ten wzorzec jest bardzo praktyczny, bo oprócz wspólnych pól dodaje kolumnę identyfikującą źródło. Dzięki niej możesz później filtrować i grupować rekordy bez zgadywania, z której tabeli pochodzi dany wiersz.

Wydajność i deduplikacja w praktyce

Największa różnica wydajnościowa wynika z konieczności usunięcia duplikatów. Przy zwykłym UNION silnik bazy musi porównać wynik, często wykorzystując sortowanie albo strukturę haszującą. Przy UNION ALL rekordy mogą zostać przekazane dalej bez tego dodatkowego etapu.

Nie oznacza to, że UNION zawsze będzie powolny. Przy małych wynikach różnica może być niezauważalna, a optymalizator konkretnego systemu bazodanowego może wybrać różne strategie. Przy setkach tysięcy lub milionach wierszy koszt deduplikacji potrafi jednak stać się istotny.

Moja praktyczna zasada jest prosta. Najpierw ustalam, czy powtórzenia są błędem, a dopiero potem patrzę na szybkość. Jeśli dane pochodzą z rozłącznych partycji, na przykład tabel sprzedaz_styczen i sprzedaz_luty, wybieram UNION ALL, bo dodatkowe usuwanie duplikatów nie daje żadnej wartości.

Z kolei przy łączeniu list klientów z kilku niezależnych systemów zwykły UNION nie rozwiązuje problemu duplikatów biznesowych. Dwa rekordy tej samej osoby mogą różnić się nazwą, formatem telefonu albo adresem, więc dla SQL nie będą identyczne. W takiej sytuacji potrzebujesz deduplikacji opartej na kluczu, na przykład przez ROW_NUMBER() lub agregację.

SELECT email
FROM (
    SELECT email FROM system_crm
    UNION ALL
    SELECT email FROM system_sprzedaz
) AS zrodla
GROUP BY email;

Takie podejście zachowuje kontrolę nad regułą unikalności. Możesz zdecydować, że identyfikatorem jest e-mail, numer klienta albo kombinacja kilku pól, zamiast zdawać się na porównanie całych wierszy.

Przykłady zastosowań, które dobrze pokazują różnicę

Lista unikalnych kategorii

SELECT kategoria
FROM produkty_online

UNION

SELECT kategoria
FROM produkty_sklep;

Jeżeli chcesz wyświetlić każdą kategorię tylko raz, UNION pasuje do celu. Nie ma znaczenia, ile produktów należy do kategorii „Laptopy”, ponieważ interesuje Cię sama lista kategorii.

Łączenie zdarzeń z wielu tabel

SELECT user_id, event_time, 'logowanie' AS event_type
FROM logowania

UNION ALL

SELECT user_id, event_time, 'zakup' AS event_type
FROM zakupy;

W raporcie aktywności użytkownika każdy rekord jest osobnym zdarzeniem. Usunięcie dwóch identycznych wierszy mogłoby zaniżyć liczbę logowań albo zakupów, dlatego UNION ALL jest tutaj bezpieczniejszym wyborem.

Łączenie danych bieżących i archiwalnych

SELECT id, kwota, data_sprzedazy
FROM sprzedaz_biezaca

UNION ALL

SELECT id, kwota, data_sprzedazy
FROM sprzedaz_archiwum;

Ten schemat spotykam często w hurtowniach danych. Jeżeli zakresy dat się nie nakładają, rekordy nie powinny się powtarzać, a zastosowanie UNION ALL ogranicza niepotrzebną pracę silnika.

Porównanie dwóch zbiorów bez łączenia kolumn

Operatory te bywają mylone z JOIN-em, ale odpowiadają na inne pytanie. UNION tworzy wspólną listę rekordów z kilku zapytań, natomiast JOIN pozwala zestawić na przykład klienta z jego zamówieniami na podstawie relacji między tabelami.

Jeżeli chcesz ustawić dane „jeden wynik pod drugim”, myśl o UNION. Jeżeli chcesz dodać informacje z drugiej tabeli do istniejącego wiersza, prawdopodobnie potrzebujesz JOIN-a.

Typowe błędy przy wyborze operatora

Użycie UNION do zwykłego sklejania danych

To najczęstszy przypadek. Programista chce połączyć dwa źródła, ale wybiera UNION, bo składnia wygląda znajomo. Skutek to ciche usunięcie powtórzeń, które może zmienić sumy, liczniki i wyniki raportów.

Założenie, że UNION usuwa każdy podobny rekord

SQL usuwa tylko wiersze identyczne w zakresie wszystkich zwracanych kolumn. Rekordy o tym samym id, ale innej dacie, cenie lub wartości typ pozostaną osobno. Gdy potrzebujesz unikalności według jednego pola, zapisz tę regułę jawnie.

Sortowanie każdej części zapytania

W większości dialektów ORDER BY umieszcza się na końcu całego wyrażenia, a nie po każdym SELECT-cie. Sortowanie poszczególnych części zwykle nie ma sensu, bo operator dopiero tworzy końcowy zbiór wynikowy.

SELECT id, nazwa
FROM produkty

UNION ALL

SELECT id, nazwa
FROM archiwum

ORDER BY nazwa;

Jeśli chcesz sortować lub ograniczać osobne zapytania, potrzebujesz nawiasów, podzapytań albo składni zależnej od używanego silnika. Szczegóły mogą różnić się między PostgreSQL, MySQL, SQL Server i Oracle, dlatego przy bardziej złożonych konstrukcjach sprawdzam plan wykonania oraz dokumentację konkretnej bazy.

Przeczytaj również: Bazy danych od podstaw - SQL, Python i dobre praktyki

Brak jawnej kontroli typów

Łączenie liczby z tekstem albo daty z niejednoznacznym ciągiem znaków może zakończyć się błędem lub nieoczekiwaną konwersją. Jawne CAST-y zwiększają czytelność i pomagają uniknąć sytuacji, w której wynik zależy od ustawień sesji lub wersji silnika.

Jak podjąć właściwą decyzję w jednym kroku

Zadaj sobie jedno pytanie: czy identyczny rekord powinien pojawić się w wyniku więcej niż raz? Jeśli odpowiedź brzmi „tak”, użyj UNION ALL. Jeśli „nie”, wybierz UNION, ale upewnij się, że identyczność całego wiersza odpowiada rzeczywistej regule biznesowej.

  • Wybierz UNION, gdy tworzysz unikalną listę wartości albo świadomie chcesz usunąć powtórzenia.
  • Wybierz UNION ALL, gdy liczysz zdarzenia, łączysz partycje lub budujesz pełny zbiór danych.
  • Dodaj kolumnę źródłową, gdy rekordy pochodzą z kilku tabel i później będziesz je analizować.
  • Przy dużych zbiorach sprawdź plan wykonania i nie dodawaj deduplikacji bez konkretnej potrzeby.

W codziennej pracy częściej zaczynam od UNION ALL, ponieważ zachowuje dane bez ukrytej utraty rekordów. Dopiero gdy wymagania mówią o unikalności, przechodzę na UNION albo stosuję precyzyjniejszą deduplikację po wybranym kluczu.

Najlepszy operator zależy od znaczenia rekordu

Różnica między tymi konstrukcjami nie sprowadza się do tego, że jedna jest „szybsza”, a druga „dokładniejsza”. UNION zmienia wynik przez usunięcie duplikatów, natomiast UNION ALL zachowuje pełną informację o liczbie wystąpień.

Dlatego przed optymalizacją zapytania sprawdzam, co reprezentuje pojedynczy wiersz i czy jego powtórzenie ma znaczenie. Ta krótka analiza zwykle prowadzi do poprawnej decyzji szybciej niż mechaniczne kierowanie się samą wydajnością.

FAQ - Najczęstsze pytania

Wybierz UNION ALL, gdy chcesz zachować każdy rekord, na przykład podczas łączenia logów, zdarzeń, sprzedaży z partycji lub danych bieżących i archiwalnych. Operator zwykle działa szybciej, ponieważ nie wykonuje deduplikacji.

Nie. UNION usuwa tylko wiersze identyczne we wszystkich zwracanych kolumnach. Jeśli rekordy tej samej osoby różnią się nazwą, telefonem lub adresem, trzeba zastosować jawną deduplikację, na przykład przez GROUP BY albo ROW_NUMBER().

Każdy SELECT musi zwracać taką samą liczbę kolumn w tej samej, zgodnej kolejności. Typy danych na odpowiadających sobie pozycjach powinny być zgodne lub możliwe do konwersji, a brakującą wartość można uzupełnić przez NULL albo stałą z odpowiednim typem.

ORDER BY zwykle umieszcza się na końcu całego wyrażenia, po ostatnim SELECT-cie. Jeśli chcesz osobno sortować lub ograniczać poszczególne zapytania, użyj nawiasów, podzapytań albo składni właściwej dla konkretnego silnika bazy danych.

UNION ustawia wyniki kilku zapytań jeden pod drugim i łączy ich wiersze. JOIN zestawia kolumny z powiązanych tabel w tym samym wierszu na podstawie relacji lub klucza.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi

join
cast
union
union all
deduplikacja
Autor Jeremi Andrzejewski
Jeremi Andrzejewski
Nazywam się Jeremi Andrzejewski i od 13 lat zajmuję się programowaniem, w szczególności w języku Python oraz nowoczesnymi technologiami. Moje zainteresowanie tymi tematami zaczęło się od pierwszych projektów, które realizowałem w szkole, a z czasem przerodziło się w pasję do rozwiązywania problemów i tworzenia innowacyjnych rozwiązań. Lubię dzielić się swoją wiedzą, szczególnie w zakresie analizy danych, automatyzacji procesów oraz tworzenia aplikacji webowych. W swojej pracy koncentruję się na dostarczaniu użytecznych, klarownych i aktualnych informacji. Staram się zawsze sprawdzać źródła, porównywać dostępne informacje i upraszczać skomplikowane zagadnienia, aby były zrozumiałe dla każdego. Wierzę, że odpowiednie zorganizowanie wiedzy oraz śledzenie najnowszych trendów w branży są kluczowe dla efektywnego nauczania i rozwoju. Cieszę się, że mogę dzielić się swoimi doświadczeniami na akademiapython.pl, gdzie mam nadzieję inspirować innych do odkrywania fascynującego świata programowania.

Udostępnij artykuł

Napisz komentarz

Komentarze

1
TO

TomaszDev

Zawsze mnie fascynowało, jak pozornie drobne różnice w składni mogą mieć tak ogromne znaczenie dla wydajności i przede wszystkim dla logiki wyników… to tak jakby wybierać między tym, co widzimy na pierwszy rzut oka, a tym, co kryje się głębiej, w całej swojej złożoności. Artykuł pięknie to ujął, że decyzja sprowadza się do tego, czy duplikaty są danymi, czy problemem. To takie… poetyckie nawet, w kontekście baz danych. Często zastanawiam się, ile razy w pośpiechu ktoś mógł użyć UNION, nie myśląc o tym, że biznesowo te powtórzenia miałyby kluczowe znaczenie, a potem wyniki były po prostu… nieprawdziwe. UNION ALL to taki cichy bohater, który po prostu robi swoje, nie oceniając, czy coś jest „takie samo”. To mi przypomina, że w życiu też czasem warto spojrzeć na wszystko, nawet na te „duplikaty”, bo mogą kryć w sobie jakąś ukrytą wartość, której na pierwszy rzut oka nie dostrzegamy… ✨

Jeremi Andrzejewski
Jeremi AndrzejewskiAutor

Bardzo dziękuję za tak wnikliwy i inspirujący komentarz! Cieszę się, że udało mi się uchwycić tę "poetykę" baz danych. :)