| Termin | Definicja |
|---|---|
| UNION | UNION łączy wyniki dwóch zapytań, usuwając duplikaty wierszy. UNION jako sposób łączenia wyników zapytańUNION jest operatorem języka SQL służącym do zestawiania rezultatów dwóch lub większej liczby zapytań SELECT w jeden wspólny wynik. Każde zapytanie przekazuje wiersze do końcowego zbioru, a następnie usuwane są powtarzające się rekordy. Dzięki temu UNION sprawdza się wtedy, gdy dane mają pochodzić z kilku źródeł, lecz mają zostać przedstawione w jednolitej tabeli wynikowej. Przykładem może być połączenie listy aktywnych klientów z listą klientów archiwalnych albo zestawienie zgłoszeń pochodzących z dwóch tabel o podobnej budowie. Wynik UNION nie jest zwykłym dopisaniem jednego zestawu wierszy pod drugim. Po połączeniu wykonywane jest rozpoznanie duplikatów na podstawie całego wiersza wynikowego. Jeżeli dwa rekordy mają identyczne wartości we wszystkich zwracanych kolumnach, w rezultacie pozostaje tylko jeden z nich. Różnica w choćby jednej kolumnie powoduje uznanie rekordów za odmienne. Ma to znaczenie przy projektowaniu zapytań, ponieważ usuwanie duplikatów wymaga dodatkowej pracy silnika bazy danych i może wpływać na czas wykonania przy dużych zbiorach. Każda część konstrukcji UNION powinna zwracać taką samą liczbę kolumn. Odpowiednie kolumny powinny mieć zgodne albo możliwe do bezpiecznej konwersji typy danych, a ich kolejność musi odpowiadać sobie pozycyjnie. Nazwy kolumn końcowego wyniku są zazwyczaj pobierane z pierwszego zapytania. Z tego powodu warto nadawać czytelne aliasy właśnie w pierwszej części konstrukcji, nawet jeżeli kolejne zapytania korzystają z innych nazw pól. UNION a UNION ALL w kontekście technicznymNajważniejszym porównaniem jest zestawienie UNION z UNION ALL. Operator UNION eliminuje identyczne wiersze, natomiast UNION ALL zachowuje każdy rekord, również wtedy, gdy taki sam rekord występuje w kilku źródłach. UNION ALL zwykle wymaga mniejszego nakładu obliczeń, ponieważ nie musi tworzyć dodatkowego zbioru służącego do deduplikacji. Z tego powodu bywa właściwszy przy łączeniu tabel, w których powtórzenia mają znaczenie, na przykład podczas scalania kolejnych partii zdarzeń, logów albo danych z okresowych importów. Wybór operatora powinien wynikać ze znaczenia danych, a nie wyłącznie z oczekiwanego wyglądu wyniku. Jeżeli dwa źródła opisują ten sam katalog i wspólny rekord powinien pojawić się tylko raz, stosowany jest UNION. Jeżeli natomiast każda obserwacja ma zostać zachowana, używany jest UNION ALL. Automatyczne usuwanie duplikatów może ukryć problem z jakością danych, ale może też być pożądanym elementem zapytania. W praktyce przed wyborem operatora określa się, czy powtórzenie oznacza błąd, czy kolejne wystąpienie tego samego zdarzenia. UNION należy odróżnić od JOIN. JOIN łączy kolumny z powiązanych tabel, tworząc szerszy wiersz na podstawie warunku relacji, na przykład wspólnego identyfikatora. UNION łączy wiersze z zapytań o zgodnym układzie kolumn, tworząc wynik dłuższy, lecz zachowujący podobny schemat. Gdy potrzebne są dane klienta oraz jego zamówienie w jednym wierszu, zwykle analizowany jest JOIN. Gdy potrzebna jest jedna lista elementów pochodzących z kilku tabel, odpowiednim kierunkiem jest UNION. Warto również odróżnić UNION od podzapytania oraz od filtrowania warunkiem OR. Podzapytanie może dostarczać wartości lub zbiór pomocniczy dla zapytania nadrzędnego, ale nie zawsze zastępuje łączenie dwóch niezależnych rezultatów. Warunek OR działa wewnątrz jednego zapytania i wybiera rekordy spełniające przynajmniej jeden warunek. UNION pozwala natomiast zbudować wynik z odrębnych instrukcji, które mogą korzystać z innych tabel, filtrów i relacji. UNION przy typowych problemach z danymiJednym z częstych problemów jest różna liczba kolumn w zapytaniach składowych. Konstrukcja nie zostanie poprawnie wykonana, jeżeli pierwsze SELECT zwróci trzy kolumny, a drugie cztery. W takiej sytuacji stosowane jest uzupełnienie brakującej pozycji stałą wartością albo wartością NULL, wraz z odpowiednim aliasem. Należy przy tym upewnić się, że typ danych pozostaje zgodny z kolumną z analogicznej pozycji. Przykładowo tekstowy opis nie powinien być bezpośrednio zestawiany z datą bez świadomej konwersji. Problemy mogą wynikać także z niejednoznacznych typów danych. Połączenie liczby całkowitej z tekstem zawierającym cyfry czasem prowadzi do automatycznej konwersji, a czasem do błędu zależnego od systemu bazy danych. Bezpieczniej jest jawnie rzutować wartości i ustalić oczekiwany typ wyniku. Szczególnej uwagi wymagają daty, wartości logiczne, identyfikatory przechowywane jako tekst oraz pola o różnych długościach. Pozostawienie konwersji decyzjom silnika może skutkować utratą precyzji albo nieoczekiwanym porządkiem sortowania. Inny problem stanowi sortowanie. ORDER BY umieszczony na końcu całej konstrukcji porządkuje końcowy wynik UNION. Wstawienie ORDER BY do pojedynczego zapytania bez zastosowania odpowiedniego opakowania może zostać odrzucone albo zadziałać inaczej, niż zakładano. W większości przypadków sortowanie powinno być wykonywane dopiero po połączeniu wszystkich źródeł. Jeżeli potrzebne jest niezależne sortowanie przed dalszym etapem obliczeń, stosowane są podzapytania lub wyrażenia tabelaryczne. Nieoczekiwane duplikaty mogą wskazywać, że rekordy różnią się wartością niewidoczną na pierwszy rzut oka. Przyczyną bywa końcowa spacja, odmienna wielkość liter, inny format daty albo różnica w wartości NULL i pustym ciągu znaków. UNION porównuje wartości zgodnie z regułami używanymi przez konkretny silnik i ustawienia kolacji. Przed uznaniem wyniku za błędny warto sprawdzić wszystkie kolumny, zastosowane typy, reguły porównywania tekstu oraz sposób reprezentowania brakujących danych. UNION w praktycznych wskazówkach projektowychPrzy budowaniu zapytania warto zacząć od opisania wspólnego znaczenia każdej kolumny. Jeżeli pierwsza pozycja oznacza identyfikator, powinna oznaczać identyfikator również w kolejnych SELECT. Mieszanie identyfikatora z nazwą albo daty z tekstowym komentarzem tworzy wynik formalnie możliwy do uzyskania, lecz trudny do dalszej analizy. Pomocne jest stosowanie tych samych aliasów, jawnych rzutowań oraz komentarzy wyjaśniających, dlaczego określone pole zostało uzupełnione wartością NULL. Dobrym zwyczajem jest testowanie każdej części osobno przed użyciem UNION. Najpierw sprawdzana jest liczba wierszy, zakres dat, typy kolumn oraz ewentualne powtórzenia w każdym źródle. Następnie analizowany jest wynik połączenia. Takie podejście ułatwia ustalenie, czy problem powstał w pierwszym zapytaniu, drugim zapytaniu, podczas konwersji typów, czy dopiero na etapie usuwania duplikatów. Przy większych tabelach należy zwracać tylko potrzebne kolumny i ograniczać źródła już na etapie poszczególnych SELECT. Filtrowanie wykonane przed UNION zwykle zmniejsza liczbę danych przekazywanych do dalszych operacji. Warto również rozważyć UNION ALL, jeśli deduplikacja nie jest wymagana. Jeżeli usuwanie duplikatów jest konieczne, pomocne bywa sprawdzenie planu wykonania i obserwacja, czy silnik korzysta z sortowania, operacji haszującej lub innych mechanizmów scalania. Przy łączeniu danych z tabel bieżących i archiwalnych przydatne jest dodanie kolumny wskazującej źródło. Dzięki temu po UNION wiadomo, z której tabeli pochodzi dany rekord. Taka kolumna może zawierać stałą wartość tekstową, na przykład „bieżące” albo „archiwalne”. Należy jednak pamiętać, że dodanie informacji o źródle zmienia sposób rozpoznawania duplikatów. Dwa identyczne rekordy z różnymi oznaczeniami źródła nie będą już identycznymi wierszami dla UNION. W bardziej rozbudowanych zapytaniach przydatne są wyrażenia WITH, które pozwalają nazwać poszczególne etapy przygotowania danych. Każde źródło może zostać najpierw oczyszczone, ujednolicone i ograniczone, a dopiero potem połączone. Poprawia to czytelność oraz ułatwia późniejszą zmianę filtrów. Przy powtarzalnych raportach należy dodatkowo sprawdzić, czy struktura tabel nie ulega zmianie, ponieważ dodanie kolumny w jednym źródle nie dostosuje automatycznie pozostałych części UNION. UNION i moment zgłoszenia problemu z komputeremTrudności z zapytaniami UNION nie zawsze wynikają z samej składni. Przyczyną mogą być błędy środowiska bazodanowego, uszkodzone pliki, problemy z pamięcią masową, niestabilność systemu albo nieprawidłowa konfiguracja narzędzia używanego do pracy z bazą. Jeżeli zapytanie wcześniej działało, a następnie zaczęło kończyć się błędem, warto zapisać dokładny komunikat, nazwę używanego programu, moment wystąpienia problemu oraz informację, czy błąd dotyczy jednego pliku, czy całego środowiska. W przypadku powtarzających się zawieszeń, nagłego spowolnienia odczytu danych, problemów z uruchomieniem aplikacji bazodanowej albo komunikatów o błędach dysku wskazana jest szybka konsultacja techniczna. Samodzielne wielokrotne uruchamianie obciążających operacji może utrudnić późniejszą diagnostykę, szczególnie gdy nośnik pamięci działa niestabilnie. W Warszawskim Pogotowiu Komputerowym 24/7 naprawy z reguły realizowane są do 3 dni roboczych, co pozwala zaplanować przekazanie sprzętu i przygotowanie informacji potrzebnych do sprawdzenia problemu. Przed zgłoszeniem warto wykonać kopię ważnych plików, o ile komputer działa wystarczająco stabilnie, oraz zanotować ostatnie zmiany w systemie. Przydatne bywają także przykładowe zapytanie, fragment komunikatu błędu i informacja o rodzaju używanej bazy danych. Tak przygotowane dane ułatwiają rozdzielenie problemu SQL od awarii sprzętowej, błędu aplikacji lub nieprawidłowego dostępu do plików. Dzięki temu UNION może zostać oceniony nie tylko jako element składni, ale jako część całego środowiska pracy z danymi. |