TOP ogranicza liczbę zwracanych wierszy zapytania, wymaga klauzuli ORDER BY dla przewidywalnego wyniku.
TOP w języku T-SQL i ograniczanie wyniku zapytania
TOP jest klauzulą języka Transact-SQL używanego przez Microsoft SQL Server. Służy do ograniczenia liczby wierszy zwracanych przez instrukcję SELECT. Najprostsza postać wygląda tak: SELECT TOP (10) kolumna1, kolumna2 FROM dbo.Tabela;. W tym przykładzie silnik zwróci najwyżej dziesięć wierszy spełniających pozostałe warunki zapytania. Liczba w nawiasie może być stałą liczbową albo wyrażeniem, którego wartość można obliczyć podczas wykonywania instrukcji.
TOP nie zmienia zawartości tabeli, lecz wpływa na zbiór wierszy przekazywany przez dane zapytanie. Klauzula może być używana również z instrukcjami INSERT, UPDATE i DELETE, gdy trzeba ograniczyć liczbę modyfikowanych rekordów. W przypadku operacji modyfikujących konieczna jest szczególna ostrożność, ponieważ bez jednoznacznego porządku wybór wierszy może nie odpowiadać oczekiwaniom administratora lub aplikacji.
ORDER BY decyduje, które wiersze znajdą się w ograniczonym zbiorze
Samo użycie TOP bez klauzuli ORDER BY określa maksymalną liczbę wyników, ale nie gwarantuje, które konkretne wiersze zostaną zwrócone. SQL Server może wykorzystać różny plan wykonania, indeks, kolejność odczytu stron danych albo inne właściwości planu. Dlatego zapytanie SELECT TOP (10) * FROM dbo.Urzadzenia; nie oznacza „dziesięć najnowszych urządzeń” ani „dziesięć urządzeń o najmniejszym identyfikatorze”. Aby uzyskać przewidywalny rezultat, trzeba wskazać regułę sortowania.
Przykładowo, SELECT TOP (10) * FROM dbo.Zgloszenia ORDER BY DataUtworzenia DESC, IdZgloszenia DESC; zwraca dziesięć zgłoszeń uporządkowanych od najnowszego. Drugi warunek sortowania pełni funkcję rozstrzygającą w sytuacji, gdy kilka rekordów ma identyczną datę. Dodanie unikalnego lub wystarczająco jednoznacznego pola do ORDER BY ogranicza ryzyko zmiany kolejności między wykonaniami. W praktyce właśnie połączenie TOP z właściwym sortowaniem definiuje sens zapytania, na przykład „ostatnie”, „najdroższe” albo „najstarsze” rekordy.
TOP procentowy, wartości zmienne i współpraca z innymi klauzulami
SQL Server pozwala ograniczać wynik nie tylko stałą liczbą wierszy, ale również procentem. Składnia SELECT TOP (10) PERCENT ... wybiera około dziesięciu procent wierszy z wyniku zapytania. Przy ograniczeniu procentowym liczba wynikowych rekordów jest obliczana przez silnik, więc nie należy zakładać, że będzie dokładnie równa prostej arytmetycznej wartości procentowej. Także tutaj potrzebne jest ORDER BY, jeśli wynik ma oznaczać konkretną grupę, na przykład dziesięć procent produktów o najwyższej cenie.
Wartość TOP może pochodzić ze zmiennej, na przykład DECLARE @Limit int = 25; SELECT TOP (@Limit) * FROM dbo.Logi ORDER BY CzasZdarzenia DESC;. W zapytaniach raportowych TOP może występować razem z WHERE, GROUP BY, HAVING i ORDER BY. Najpierw należy precyzyjnie określić, jaki zbiór ma być analizowany, a następnie ustalić kolejność wyboru. Jeżeli potrzebne jest pobieranie kolejnych stron danych, samo TOP nie wystarcza do zbudowania stabilnej paginacji. W SQL Server często stosuje się wtedy ORDER BY wraz z OFFSET i FETCH NEXT, ponieważ te elementy opisują zarówno pominięcie wcześniejszych wierszy, jak i liczbę pobieranych rekordów.
Kontrola zapytań TOP podczas analizy działania SQL Server
Podczas diagnostyki aplikacji korzystającej z SQL Server warto sprawdzić, czy TOP odpowiada rzeczywistej intencji kodu. Częstym błędem jest ograniczenie wyniku do kilku rekordów bez ORDER BY, a następnie traktowanie otrzymanego wiersza jako najnowszego, najstarszego lub reprezentatywnego. Innym problemem jest sortowanie po kolumnie, która nie rozstrzyga remisów, na przykład wyłącznie po dacie zapisu. Wtedy dwa wykonania tego samego zapytania mogą zwrócić rekordy w innej kolejności, zwłaszcza po zmianie indeksu lub planu wykonania.
Weryfikacja powinna obejmować tekst zapytania, typy danych kolumn użytych w ORDER BY, indeksy oraz plan wykonania. Indeks może zmniejszyć koszt odczytu, ale nie zastępuje jawnego sortowania w kodzie. Należy także odróżnić ograniczenie wierszy od ograniczenia danych pobieranych przez aplikację: TOP działa po stronie SQL Server, natomiast limit w kodzie klienta może obcinać już odebrane dane. Przy instrukcjach UPDATE i DELETE trzeba potwierdzić warunek WHERE, kolejność wyboru oraz liczbę zmodyfikowanych rekordów, ponieważ TOP ogranicza operację, lecz sam nie opisuje biznesowej reguły wyboru.