JOIN z TOP to konstrukcja łącząca tabele i ograniczająca wynik do wskazanej liczby pierwszych wierszy.
Jak działa JOIN z TOP w SQL Server
W SQL Server konstrukcja łącząca JOIN z TOP służy do pobrania ograniczonej liczby wierszy powstałych po połączeniu dwóch lub większej liczby tabel. JOIN określa sposób dopasowania rekordów, natomiast TOP ogranicza liczbę wierszy zwracanych przez całe zapytanie. Przykładowo zapytanie w postaci SELECT TOP (20) k.id, k.nazwa, z.data_zamowienia FROM Klienci AS k INNER JOIN Zamowienia AS z ON z.klient_id = k.id ORDER BY z.data_zamowienia DESC; zwróci maksymalnie 20 najnowszych zamówień wraz z danymi powiązanych klientów.
W przypadku INNER JOIN wynik zawiera tylko rekordy, dla których warunek połączenia jest spełniony w obu tabelach. Przy LEFT JOIN SQL Server zachowuje wszystkie wiersze z tabeli znajdującej się po lewej stronie, a brak dopasowania po prawej stronie reprezentuje wartościami NULL. Operator TOP ogranicza wynik po wykonaniu logicznego połączenia, dlatego nie oznacza automatycznie pobrania określonej liczby rekordów z każdej tabeli.
Znaczenie kolejności i warunku ORDER BY
Samo użycie TOP bez ORDER BY nie definiuje, które wiersze zostaną wybrane. SQL Server może zwrócić dowolny podzbiór rekordów zgodny z planem wykonania, a jego rezultat może zmienić się po utworzeniu indeksu, aktualizacji statystyk, zmianie planu lub modyfikacji danych. Dlatego zapytanie SELECT TOP (10) ... FROM A JOIN B ON ... ogranicza liczbę wierszy, ale nie gwarantuje ich kolejności ani powtarzalnego wyboru.
Jeżeli wynik ma przedstawiać konkretny wycinek danych, należy użyć ORDER BY, na przykład ORDER BY z.data_zamowienia DESC, z.id DESC. Dodanie drugiej kolumny, takiej jak unikalny identyfikator, pomaga rozstrzygnąć remisy, gdy wiele rekordów ma tę samą datę. Bez takiego dodatkowego kryterium kolejność wierszy o identycznej wartości sortowania może pozostać nieokreślona. W zapytaniu z SELECT DISTINCT sortowanie musi być zgodne z zasadami SQL Server dotyczącymi kolumn obecnych w liście wyboru.
TOP po połączeniu tabel i warianty ograniczania wyniku
SQL Server pozwala zapisać limit jako TOP (n), gdzie n jest stałą lub wyrażeniem obliczanym w czasie wykonania. Można również użyć TOP (n) PERCENT, aby zwrócić określony procent wierszy, oraz WITH TIES, aby dołączyć dodatkowe rekordy mające taką samą wartość sortowania jak ostatni wybrany wiersz. Na przykład SELECT TOP (10) WITH TIES ... ORDER BY z.kwota DESC może zwrócić więcej niż 10 wierszy, jeśli kolejne rekordy mają identyczną kwotę.
Jeżeli wymaganiem jest pobranie kilku rekordów dla każdej grupy, zwykłe TOP nie wystarczy, ponieważ działa na całym zbiorze wynikowym. W SQL Server stosuje się wtedy funkcję okienkową, na przykład ROW_NUMBER() OVER (PARTITION BY k.id ORDER BY z.data_zamowienia DESC), a następnie filtruje wiersze o numerze nie większym niż określony limit. Trzeba także uwzględnić możliwość zwielokrotnienia wierszy: jeśli jeden klient ma wiele zamówień, połączenie klienta z zamówieniami zwróci osobny wiersz dla każdego zamówienia. Zastosowanie TOP (10) ograniczy więc zamówienia, a niekoniecznie dziesięciu różnych klientów.
Diagnostyka zapytań JOIN z TOP
Nieoczekiwany wynik warto analizować od warunku ON, rodzaju złączenia i liczności relacji między tabelami. Błędny warunek może pominąć rekordy, natomiast połączenie tabeli nadrzędnej z tabelą zawierającą wiele rekordów podrzędnych może utworzyć duplikaty. Jeżeli filtr dotyczący tabeli po prawej stronie LEFT JOIN zostanie umieszczony w klauzuli WHERE, może wyeliminować wiersze z wartościami NULL i w praktyce zmienić rezultat podobny do INNER JOIN. Przeniesienie warunku do klauzuli ON często zachowuje zamierzony charakter lewego złączenia.
Podczas diagnostyki należy sprawdzić plan wykonania, indeksy używane do warunku połączenia i kolumn sortowania oraz rzeczywistą liczbę wierszy przed zastosowaniem limitu. W SQL Server pomocne jest uruchomienie zapytania z metrykami wejścia-wyjścia i czasu, a także porównanie wyniku z wersją bez TOP. Gdy celem jest stronicowanie, można rozważyć ORDER BY ... OFFSET ... ROWS FETCH NEXT ... ROWS ONLY, ale także ta forma wymaga stabilnego sortowania. Przy naprawie problemów z komputerem, na którym działa narzędzie korzystające z takich zapytań, diagnostyka powinna obejmować zarówno kod SQL, jak i połączenie z bazą, sterownik oraz lokalne zasoby systemowe.