В SQL Server можете да използвате TOP
клауза за ограничаване на редовете, върнати от набор от резултати от заявка. Тази клауза предоставя подобна функционалност на LIMIT
в MySQL и ROWNUM
в Oracle, въпреки че има разлики в начина на работа на всеки от тях.
По-долу са дадени примери за използване на TOP
клауза за ограничаване на набора от резултати в SQL Server.
Пример 1 – Основна употреба
Ето основен пример за това как TOP
работи:
SELECT TOP(3) * FROM Albums;
Резултат:
+-----------+-----------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-----------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 2 | Powerage | 1978-05-05 | 2 | 1 | | 3 | Singing Down the Lane | 1956-01-01 | 6 | 3 | +-----------+-----------------------+---------------+------------+-----------+
В този случай ограничих резултатите само до три реда.
Нека стартираме заявката отново, но този път без TOP
клауза:
SELECT * FROM Albums;
Резултат:
+-----------+--------------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+--------------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 2 | Powerage | 1978-05-05 | 2 | 1 | | 3 | Singing Down the Lane | 1956-01-01 | 6 | 3 | | 4 | Ziltoid the Omniscient | 2007-05-21 | 5 | 1 | | 5 | Casualties of Cool | 2014-05-14 | 5 | 1 | | 6 | Epicloud | 2012-09-18 | 5 | 1 | | 7 | Somewhere in Time | 1986-09-29 | 1 | 1 | | 8 | Piece of Mind | 1983-05-16 | 1 | 1 | | 9 | Killers | 1981-02-02 | 1 | 1 | | 10 | No Prayer for the Dying | 1990-10-01 | 1 | 1 | | 11 | No Sound Without Silence | 2014-09-12 | 9 | 4 | | 12 | Big Swing Face | 1967-06-01 | 4 | 2 | | 13 | Blue Night | 2000-11-01 | 12 | 4 | | 14 | Eternity | 2008-10-27 | 12 | 4 | | 15 | Scandinavia | 2012-06-11 | 12 | 4 | | 16 | Long Lost Suitcase | 2015-10-09 | 7 | 4 | | 17 | Praise and Blame | 2010-06-26 | 7 | 4 | | 18 | Along Came Jones | 1965-05-21 | 7 | 4 | | 19 | All Night Wrong | 2002-05-05 | 3 | 2 | | 20 | The Sixteen Men of Tain | 2000-03-20 | 3 | 2 | | 21 | Yo Wassup | 2019-03-12 | 9 | 3 | | 22 | Busted | 1901-05-11 | 9 | 3 | +-----------+--------------------------+---------------+------------+-----------+
Така можем да видим, че първата заявка върна само първите три от по-голям набор.
Пример 2 – Използване на клаузата ORDER BY
Microsoft заявява, че е най-добрата практика винаги да използвате ORDER BY
когато използвате TOP
клауза. Това е така, защото това е единственият начин да се посочи предвидимо кои редове са засегнати от TOP
.
Следователно бихме могли да пренапишем първия пример на следното:
SELECT TOP(3) * FROM Albums ORDER BY AlbumId;
Резултат:
+-----------+-----------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-----------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 2 | Powerage | 1978-05-05 | 2 | 1 | | 3 | Singing Down the Lane | 1956-01-01 | 6 | 3 | +-----------+-----------------------+---------------+------------+-----------+
Важно е да разберете как подреждането влияе на резултатите. В противен случай можете да завършите с неочаквани резултати.
Ето какво се случва, ако използвам отново същата заявка, но подредя по друга колона:
SELECT TOP(3) * FROM Albums ORDER BY ArtistId;
Резултат:
+-----------+-------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 7 | Somewhere in Time | 1986-09-29 | 1 | 1 | | 8 | Piece of Mind | 1983-05-16 | 1 | 1 | +-----------+-------------------+---------------+------------+-----------+
Вмъкване, изтриване и актуализиране в поръчка
Имайте предвид, че въпреки че можете да използвате TOP
клауза в INSERT
, UPDATE
, MERGE
и DELETE
оператори, не можете директно да посочите ORDER BY
клауза в тези изявления. Можете обаче да използвате израз за подизбиране, за да вмъквате, изтривате или променяте редове в смислен хронологичен ред.
Пример 3 – Използване на аргумента WITH TIES
Можете да използвате незадължителния WITH TIES
аргумент за връщане на всички редове, които се свързват за последното място в ограничения набор от резултати. Това е приложимо (и може да се използва само) при използване на ORDER BY
клауза.
Ако ORDER BY
клаузата кара два или повече реда да се обвържат за последно място, като се използва WITH TIES
, ще накара всички те да бъдат върнати. Това може да доведе до връщане на повече редове, отколкото всъщност сте посочили.
Това се обяснява по-лесно с пример.
SELECT TOP(3) WITH TIES * FROM Albums ORDER BY ArtistId;
Резултат:
+-----------+-------------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 7 | Somewhere in Time | 1986-09-29 | 1 | 1 | | 8 | Piece of Mind | 1983-05-16 | 1 | 1 | | 9 | Killers | 1981-02-02 | 1 | 1 | | 10 | No Prayer for the Dying | 1990-10-01 | 1 | 1 | +-----------+-------------------------+---------------+------------+-----------+
Тук уточнявам, че трябва да се връщат само горните 3 реда, но всъщност 5 се връщат. Това е така, защото има 5 реда, използващи един и същ ArtistId, и така всички редове 3 – 5 се връзват за последното място. В този случай използвам WITH TIES
да ги върне всичките.
Ако премахна WITH TIES
, се връщат само 3 реда:
SELECT TOP(3) * FROM Albums ORDER BY ArtistId;
Резултат:
+-----------+-------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 7 | Somewhere in Time | 1986-09-29 | 1 | 1 | | 8 | Piece of Mind | 1983-05-16 | 1 | 1 | +-----------+-------------------+---------------+------------+-----------+
Обърнете внимание, че WITH TIES
Аргументът може да бъде зададен само в SELECT
оператори и само ако използват ORDER BY
клауза. Също така върнатият ред на обвързване на записи е произволен.
Пример 4 – Използване на проценти
Освен това имате възможност да посочите процентна стойност вместо определен брой редове. За да направите това, използвайте PERCENT
аргумент.
Пример:
SELECT TOP(10) PERCENT * FROM Albums ORDER BY AlbumId;
Резултат:
+-----------+-----------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+-----------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 2 | Powerage | 1978-05-05 | 2 | 1 | | 3 | Singing Down the Lane | 1956-01-01 | 6 | 3 | +-----------+-----------------------+---------------+------------+-----------+
Имайте предвид, че дробните стойности се закръгляват до следващата целочислена стойност. В този случай 10 процента от 22 реда са 2,2, но тъй като е закръглено, в крайна сметка получаваме 3 реда.
Така че удвояването на процента няма да доведе непременно до удвояване на броя на редовете:
SELECT TOP(20) PERCENT * FROM Albums ORDER BY AlbumId;
Резултат:
+-----------+------------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+------------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 2 | Powerage | 1978-05-05 | 2 | 1 | | 3 | Singing Down the Lane | 1956-01-01 | 6 | 3 | | 4 | Ziltoid the Omniscient | 2007-05-21 | 5 | 1 | | 5 | Casualties of Cool | 2014-05-14 | 5 | 1 | +-----------+------------------------+---------------+------------+-----------+
В този случай 20 процента от 22 е 4,4. Още веднъж се закръгля нагоре и получаваме 5 реда.
Пример 5 – Премахване на скоби
Възможно е да премахнете скобите, когато използвате TOP
клауза обаче не се препоръчва.
Така или иначе, ето пример за премахване на скоби от предишния пример:
SELECT TOP 20 PERCENT * FROM Albums ORDER BY AlbumId;
Резултат:
+-----------+------------------------+---------------+------------+-----------+ | AlbumId | AlbumName | ReleaseDate | ArtistId | GenreId | |-----------+------------------------+---------------+------------+-----------| | 1 | Powerslave | 1984-09-03 | 1 | 1 | | 2 | Powerage | 1978-05-05 | 2 | 1 | | 3 | Singing Down the Lane | 1956-01-01 | 6 | 3 | | 4 | Ziltoid the Omniscient | 2007-05-21 | 5 | 1 | | 5 | Casualties of Cool | 2014-05-14 | 5 | 1 | +-----------+------------------------+---------------+------------+-----------+
Microsoft препоръчва винаги да използвате скоби, тъй като те осигуряват последователност с изискваната им употреба в INSERT
, UPDATE
, MERGE
и DELETE
изявления.
Скобите са незадължителни от съображения за обратна съвместимост.