Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Limitar as linhas retornadas em uma consulta do SQL Server usando a cláusula TOP


No SQL Server, você pode usar o TOP cláusula para limitar as linhas retornadas de um conjunto de resultados de consulta. Esta cláusula fornece funcionalidade semelhante a LIMIT no MySQL e ROWNUM no Oracle, embora haja diferenças em como cada um deles funciona.

Abaixo estão exemplos de uso do TOP cláusula para limitar o conjunto de resultados no SQL Server.


Exemplo 1 – Uso básico


Aqui está um exemplo básico de como TOP funciona:
SELECT TOP(3) * 
FROM Albums;

Resultado:
+-----------+-----------------------+---------------+------------+-----------+
| 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         |
+-----------+-----------------------+---------------+------------+-----------+

Nesse caso, limitei os resultados a apenas três linhas.

Vamos executar a consulta novamente, mas desta vez sem o TOP cláusula:
SELECT * 
FROM Albums;

Resultado:
+-----------+--------------------------+---------------+------------+-----------+
| 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         |
+-----------+--------------------------+---------------+------------+-----------+

Assim, podemos ver que a primeira consulta retornou apenas as três primeiras de um conjunto maior.

Exemplo 2 – Usando a cláusula ORDER BY


A Microsoft afirma que é uma prática recomendada sempre usar o ORDER BY ao usar o TOP cláusula. Isso ocorre porque é a única maneira de indicar previsivelmente quais linhas são afetadas por TOP .

Portanto, poderíamos reescrever o primeiro exemplo para o seguinte:
SELECT TOP(3) * 
FROM Albums
ORDER BY AlbumId;

Resultado:
+-----------+-----------------------+---------------+------------+-----------+
| 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         |
+-----------+-----------------------+---------------+------------+-----------+

É importante entender como a ordenação afeta os resultados. Caso contrário, você pode acabar com resultados inesperados.

Aqui está o que acontece se eu usar a mesma consulta novamente, mas ordenar por uma coluna diferente:
SELECT TOP(3) * 
FROM Albums
ORDER BY ArtistId;

Resultado:
+-----------+-------------------+---------------+------------+-----------+
| 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         |
+-----------+-------------------+---------------+------------+-----------+

Inserindo, excluindo e atualizando em ordem


Observe que, embora você possa usar o TOP cláusula em INSERT , UPDATE , MERGE e DELETE instruções, você não pode especificar diretamente o ORDER BY cláusula nestas declarações. No entanto, você pode usar uma instrução de subseleção para inserir, excluir ou modificar linhas em uma ordem cronológica significativa.

Exemplo 3 – Usando o argumento WITH TIES


Você pode usar o opcional WITH TIES argumento para retornar todas as linhas empatadas em último lugar no conjunto de resultados limitado. Isso só é aplicável (e só pode ser usado) ao usar o ORDER BY cláusula.

Se o ORDER BY cláusula faz com que duas ou mais linhas fiquem empatadas em último lugar, usando WITH TIES , fará com que todos sejam devolvidos. Isso pode fazer com que mais linhas sejam retornadas do que você realmente especificou.

Isso é mais fácil de explicar com um exemplo.
SELECT TOP(3) WITH TIES *
FROM Albums
ORDER BY ArtistId;

Resultado:
+-----------+-------------------------+---------------+------------+-----------+
| 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         |
+-----------+-------------------------+---------------+------------+-----------+

Aqui, especifico que apenas as 3 primeiras linhas devem ser retornadas, mas 5 são realmente retornadas. Isso ocorre porque há 5 linhas usando o mesmo ArtistId e, portanto, as linhas 3 a 5 estão todas empatadas no último lugar. Neste caso eu uso WITH TIES para devolvê-los todos.

Se eu remover WITH TIES , apenas 3 linhas são retornadas:
SELECT TOP(3) *
FROM Albums
ORDER BY ArtistId;

Resultado:
+-----------+-------------------+---------------+------------+-----------+
| 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         |
+-----------+-------------------+---------------+------------+-----------+

Observe que o WITH TIES argumento só pode ser especificado em SELECT instruções, e somente se eles usarem o ORDER BY cláusula. Além disso, a ordem retornada dos registros vinculados é arbitrária.

Exemplo 4 – Usando porcentagens


Você também tem a opção de especificar um valor percentual em vez de um número definido de linhas. Para fazer isso, use o PERCENT argumento.

Exemplo:
SELECT TOP(10) PERCENT * 
FROM Albums
ORDER BY AlbumId;

Resultado:
+-----------+-----------------------+---------------+------------+-----------+
| 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         |
+-----------+-----------------------+---------------+------------+-----------+

Observe que os valores fracionários são arredondados para o próximo valor inteiro. Nesse caso, 10% de 22 linhas são 2,2, mas, como foi arredondado, acabamos com 3 linhas.

Portanto, dobrar a porcentagem não resultará necessariamente no dobro do número de linhas:
SELECT TOP(20) PERCENT * 
FROM Albums
ORDER BY AlbumId;

Resultado:
+-----------+------------------------+---------------+------------+-----------+
| 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         |
+-----------+------------------------+---------------+------------+-----------+

Nesse caso, 20% de 22 é 4,4. Mais uma vez, é arredondado e obtemos 5 linhas.

Exemplo 5 – Removendo os parênteses


É possível remover os parênteses ao usar o TOP cláusula, no entanto, não é recomendado.

De qualquer forma, aqui está um exemplo de remoção dos parênteses do exemplo anterior:
SELECT TOP 20 PERCENT * 
FROM Albums
ORDER BY AlbumId;

Resultado:
+-----------+------------------------+---------------+------------+-----------+
| 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         |
+-----------+------------------------+---------------+------------+-----------+

A Microsoft recomenda que você sempre use os parênteses, pois fornece consistência com o uso necessário em INSERT , UPDATE , MERGE e DELETE declarações.

Os parênteses são opcionais por motivos de compatibilidade com versões anteriores.