Trong SQL Server, bạn có thể sử dụng TOP
để giới hạn các hàng được trả về từ tập kết quả truy vấn. Điều khoản này cung cấp chức năng tương tự cho LIMIT
trong MySQL và ROWNUM
trong Oracle, mặc dù có sự khác biệt về cách hoạt động của từng thứ.
Dưới đây là các ví dụ về việc sử dụng TOP
để giới hạn kết quả được đặt trong SQL Server.
Ví dụ 1 - Cách sử dụng cơ bản
Đây là một ví dụ cơ bản về cách TOP
hoạt động:
SELECT TOP(3) * FROM Albums;
Kết quả:
+-----------+-----------------------+---------------+------------+-----------+ | 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 | +-----------+-----------------------+---------------+------------+-----------+
Trong trường hợp này, tôi giới hạn kết quả chỉ trong ba hàng.
Hãy chạy lại truy vấn, nhưng lần này không có TOP
mệnh đề:
SELECT * FROM Albums;
Kết quả:
+-----------+--------------------------+---------------+------------+-----------+ | 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 | +-----------+--------------------------+---------------+------------+-----------+
Vì vậy, chúng ta có thể thấy rằng truy vấn đầu tiên chỉ trả về ba truy vấn đầu tiên từ một tập hợp lớn hơn.
Ví dụ 2 - Sử dụng Mệnh đề ORDER BY
Microsoft tuyên bố rằng cách tốt nhất là luôn sử dụng ORDER BY
khi sử dụng TOP
mệnh đề. Điều này là do, đó là cách duy nhất để cho biết có thể đoán trước được những hàng nào bị ảnh hưởng bởi TOP
.
Do đó, chúng tôi có thể viết lại ví dụ đầu tiên thành sau:
SELECT TOP(3) * FROM Albums ORDER BY AlbumId;
Kết quả:
+-----------+-----------------------+---------------+------------+-----------+ | 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 | +-----------+-----------------------+---------------+------------+-----------+
Điều quan trọng là phải hiểu cách đặt hàng ảnh hưởng đến kết quả. Nếu không, bạn có thể nhận được kết quả không mong muốn.
Đây là điều sẽ xảy ra nếu tôi sử dụng lại cùng một truy vấn nhưng sắp xếp theo một cột khác:
SELECT TOP(3) * FROM Albums ORDER BY ArtistId;
Kết quả:
+-----------+-------------------+---------------+------------+-----------+ | 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 | +-----------+-------------------+---------------+------------+-----------+
Chèn, xóa và cập nhật theo thứ tự
Lưu ý rằng, mặc dù bạn có thể sử dụng TOP
mệnh đề trong INSERT
, UPDATE
, MERGE
và DELETE
câu lệnh, bạn không thể chỉ định trực tiếp ORDER BY
mệnh đề trong các câu lệnh này. Tuy nhiên, bạn có thể sử dụng câu lệnh chọn phụ để chèn, xóa hoặc sửa đổi các hàng theo thứ tự thời gian có ý nghĩa.
Ví dụ 3 - Sử dụng Đối số VỚI TIES
Bạn có thể sử dụng WITH TIES
tùy chọn đối số để trả về tất cả các hàng ràng buộc ở vị trí cuối cùng trong tập kết quả giới hạn. Điều này chỉ áp dụng (và chỉ có thể được sử dụng) khi sử dụng ORDER BY
mệnh đề.
Nếu ORDER BY
mệnh đề khiến hai hoặc nhiều hàng buộc ở vị trí cuối cùng, sử dụng WITH TIES
, sẽ khiến tất cả chúng được trả lại. Điều này có thể khiến nhiều hàng được trả lại hơn bạn thực sự chỉ định.
Điều này được giải thích dễ dàng hơn với một ví dụ.
SELECT TOP(3) WITH TIES * FROM Albums ORDER BY ArtistId;
Kết quả:
+-----------+-------------------------+---------------+------------+-----------+ | 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 | +-----------+-------------------------+---------------+------------+-----------+
Ở đây, tôi chỉ định rằng chỉ 3 hàng trên cùng nên được trả lại, nhưng 5 hàng thực sự được trả về. Điều này là do có 5 hàng sử dụng cùng một ArtistId, và vì vậy các hàng 3 - 5 đều buộc ở vị trí cuối cùng. Trong trường hợp này, tôi sử dụng WITH TIES
để trả lại tất cả.
Nếu tôi xóa WITH TIES
, chỉ có 3 hàng được trả lại:
SELECT TOP(3) * FROM Albums ORDER BY ArtistId;
Kết quả:
+-----------+-------------------+---------------+------------+-----------+ | 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 | +-----------+-------------------+---------------+------------+-----------+
Lưu ý rằng WITH TIES
đối số chỉ có thể được chỉ định trong SELECT
và chỉ khi chúng sử dụng ORDER BY
mệnh đề. Ngoài ra, thứ tự buộc các bản ghi được trả về là tùy ý.
Ví dụ 4 - Sử dụng Phần trăm
Bạn cũng có tùy chọn chỉ định giá trị phần trăm thay vì một số hàng đã đặt. Để thực hiện việc này, hãy sử dụng PERCENT
đối số.
Ví dụ:
SELECT TOP(10) PERCENT * FROM Albums ORDER BY AlbumId;
Kết quả:
+-----------+-----------------------+---------------+------------+-----------+ | 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 | +-----------+-----------------------+---------------+------------+-----------+
Lưu ý rằng các giá trị phân số được làm tròn đến giá trị số nguyên tiếp theo. Trong trường hợp này, 10 phần trăm của 22 hàng là 2,2, nhưng vì nó đã được làm tròn, chúng tôi kết thúc với 3 hàng.
Vì vậy, tăng gấp đôi tỷ lệ phần trăm, sẽ không nhất thiết dẫn đến tăng gấp đôi số hàng:
SELECT TOP(20) PERCENT * FROM Albums ORDER BY AlbumId;
Kết quả:
+-----------+------------------------+---------------+------------+-----------+ | 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 | +-----------+------------------------+---------------+------------+-----------+
Trong trường hợp này, 20 phần trăm của 22 là 4,4. Một lần nữa, nó được làm tròn và chúng ta có 5 hàng.
Ví dụ 5 - Loại bỏ dấu ngoặc đơn
Có thể bỏ dấu ngoặc đơn khi sử dụng TOP
Tuy nhiên, điều này không được khuyến khích.
Dù bằng cách nào, đây là một ví dụ về cách xóa dấu ngoặc đơn từ ví dụ trước:
SELECT TOP 20 PERCENT * FROM Albums ORDER BY AlbumId;
Kết quả:
+-----------+------------------------+---------------+------------+-----------+ | 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 khuyến nghị bạn luôn sử dụng dấu ngoặc đơn vì nó cung cấp tính nhất quán với việc sử dụng bắt buộc trong INSERT
, UPDATE
, MERGE
và DELETE
tuyên bố.
Dấu ngoặc đơn là tùy chọn vì lý do tương thích ngược.