No PostgreSQL, existem as palavras Limit
- Offset
chave e que permitirão uma paginação muito fácil dos conjuntos de resultados.
Qual é a sintaxe equivalente para o SQL Server?
No PostgreSQL, existem as palavras Limit
- Offset
chave e que permitirão uma paginação muito fácil dos conjuntos de resultados.
Qual é a sintaxe equivalente para o SQL Server?
Respostas:
O equivalente a LIMIT
é SET ROWCOUNT
, mas se você quiser paginação genérica, é melhor escrever uma consulta como esta:
;WITH Results_CTE AS
(
SELECT
Col1, Col2, ...,
ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
FROM Table
WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @Offset
AND RowNum < @Offset + @Limit
A vantagem aqui é a parametrização do deslocamento e do limite, caso você decida alterar suas opções de paginação (ou permita que o usuário faça isso).
Nota: o @Offset
parâmetro deve usar a indexação baseada em um para isso, em vez da indexação normal baseada em zero.
WHERE RowNum >= (@Offset + 1)
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified
. MSSQL2008 R2.
Table
tiver 200k registros, ele buscará todos primeiro e aplicará o limite? Esta consulta é eficiente?
Agora, esse recurso foi facilitado no SQL Server 2012. Isso está funcionando a partir do SQL Server 2012.
Limite com deslocamento para selecionar 11 a 20 linhas no SQL Server:
SELECT email FROM emailTable
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
OFFSET
: número de linhas ignoradasNEXT
: número necessário de próximas linhasReferência: https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017
SQL_CALC_FOUND_ROWS
ao usar isso?
select top {LIMIT HERE} * from (
select *, ROW_NUMBER() over (order by {ORDER FIELD}) as r_n_n
from {YOUR TABLES} where {OTHER OPTIONAL FILTERS}
) xx where r_n_n >={OFFSET HERE}
Nota:
Esta solução funcionará apenas no SQL Server 2005 ou superior, pois foi quando ROW_NUMBER()
foi implementada.
AS xx
Para mim, o uso de OFFSET e FETCH juntos foi lento, então usei uma combinação de TOP e OFFSET como este (que foi mais rápido):
SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Nota: Se você usar TOP e OFFSET juntos na mesma consulta, como:
SELECT TOP 20 columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS
Então você recebe um erro; portanto, para usar TOP e OFFSET juntos, é necessário separá-lo com uma subconsulta.
E se você precisar usar SELECT DISTINCT, a consulta será como:
SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Nota: O uso de SELECT ROW_NUMBER com DISTINCT não funcionou para mim.
SELECT TOP 20 id FROM table1 where id > 10 order by date OFFSET 20 rows
, deve transformá-lo SELECT TOP 20 * FROM (SELECT id FROM table1 where id > 10 order by date OFFSET 20 ROWS) t1
. Vou editar minha resposta. Obrigado e com licença meu inglês.
Outra amostra:
declare @limit int
declare @offset int
set @offset = 2;
set @limit = 20;
declare @count int
declare @idxini int
declare @idxfim int
select @idxfim = @offset * @limit
select @idxini = @idxfim - (@limit-1);
WITH paging AS
(
SELECT
ROW_NUMBER() OVER (order by object_id) AS rowid, *
FROM
sys.objects
)
select *
from
(select COUNT(1) as rowqtd from paging) qtd,
paging
where
rowid between @idxini and @idxfim
order by
rowid;
Existe aqui alguém dizendo sobre esse recurso no sql 2011, é triste que eles escolham uma palavra-chave um pouco diferente "OFFSET / FETCH", mas não é padrão então ok.
Adicionando uma pequena variação na solução da Aaronaught, normalmente parametrizo o número da página (@PageNum) e o tamanho da página (@PageSize). Dessa forma, cada evento de clique na página envia o número da página solicitada junto com um tamanho de página configurável:
begin
with My_CTE as
(
SELECT col1,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
select * from My_CTE
WHERE RowNum BETWEEN (@PageNum - 1) * (@PageSize + 1)
AND @PageNum * @PageSize
end
O mais próximo que eu poderia fazer é
select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber
Que eu acho parecido com select * from [db].[dbo].[table] LIMIT 0, 10
@nombre_row :nombre ligne par page
@page:numero de la page
//--------------code sql---------------
declare @page int,@nombre_row int;
set @page='2';
set @nombre_row=5;
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY etudiant_ID ) AS RowNum, *
FROM etudiant
) AS RowConstrainedResult
WHERE RowNum >= ((@page-1)*@nombre_row)+1
AND RowNum < ((@page)*@nombre_row)+1
ORDER BY RowNum
Como ninguém forneceu esse código ainda:
SELECT TOP @limit f1, f2, f3...
FROM t1
WHERE c1 = v1, c2 > v2...
AND
t1.id NOT IN
(SELECT TOP @offset id
FROM t1
WHERE c1 = v1, c2 > v2...
ORDER BY o1, o2...)
ORDER BY o1, o2...
Pontos importantes:
@limit
pode ser substituído pelo número de resultados a serem recuperados,@offset
é o número de resultados a serem ignoradoswhere
e order by
cláusula e fornece resultados incorretos se estiverem fora de sincroniaorder by
existe explicitamente se é isso que é necessárioEspecificamente para o SQL-SERVER, você pode conseguir isso de várias maneiras diferentes. Para um exemplo real, usamos a tabela Customer aqui.
Exemplo 1: Com "SET ROWCOUNT"
SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Para retornar todas as linhas, defina ROWCOUNT como 0
SET ROWCOUNT 0
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Exemplo 2: Com "ROW_NUMBER and OVER"
With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (order by CompanyName) as RowNumber
FROM Customers )
select *
from Cust
Where RowNumber Between 0 and 10
Exemplo 3: Com "OFFSET and FETCH", mas com este "ORDER BY" é obrigatório
SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
Espero que isso ajude você.
Desde então, eu testo mais vezes esse script mais útil em 1 milhão de registros a cada página. 100 registros com paginação funcionam mais rápido meu PC executa esse script 0 segundos, enquanto a comparação com o mysql tem limite próprio e desloca cerca de 4,5 segundos para obter o resultado.
Alguém pode deixar de entender Row_Number () sempre classificar por campo específico. Caso seja necessário definir apenas a linha em sequência, deve-se usar:
SELECT TOP {LIMIT} * FROM (
SELECT TOP {LIMIT} + {OFFSET} ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ROW_NO,*
FROM {TABLE_NAME}
) XX WHERE ROW_NO > {OFFSET}
Explicar: