start - sql server offset
¿Equivalente a LIMIT y OFFSET para SQL Server? (14)
En PostgreSQL existen las palabras clave de Limit
y Offset
que permitirán una paginación muy fácil de los conjuntos de resultados.
¿Cuál es la sintaxis equivalente para Sql Server?
Agregando una ligera variación en la solución de Aaronaught, típicamente parametrizo el número de página (@PageNum) y el tamaño de página (@PageSize). De esta forma, cada evento de clic de página solo envía el número de página solicitado junto con un tamaño de página configurable:
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
Aquí hay alguien que habla sobre esta función en sql 2011, es triste que elijan una palabra clave diferente "OFFSET / FETCH" pero no es estándar, entonces está bien.
Dado que nadie proporcionó este código todavía:
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...
Puntos importantes:
- ORDER BY debe ser idéntico
-
@limit
puede ser reemplazado por la cantidad de resultados a recuperar, -
@offset
es el número de resultados para omitir - Compare el rendimiento con las soluciones anteriores, ya que pueden ser más eficientes
- esta solución duplica las cláusulas
where
yorder by
, y proporcionará resultados incorrectos si no están sincronizados - por otro lado
order by
está allí explícitamente si eso es lo que se necesita
El equivalente de LIMIT
es SET ROWCOUNT
, pero si desea una paginación genérica, es mejor escribir una 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
La ventaja aquí es la parametrización de la compensación y el límite en caso de que decida cambiar sus opciones de búsqueda (o permitir que el usuario lo haga).
Nota: el parámetro @Offset
debe usar indexación basada en uno para esto en lugar de la indexación basada en cero normal.
En SQL server usaría TOP junto con ROW_NUMBER ()
Esta característica ahora es más fácil en el servidor sql 2012. Esto funciona pero el servidor sql 2012 en adelante. Límite con desplazamiento para seleccionar de 11 a 20 filas en el servidor sql:
SELECT email FROM emailTable
WHERE id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
// offset - no. de filas salteadas
// siguiente - requerido no. de las próximas filas
Lo más cercano que pude hacer es
select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber
Lo cual creo que es similar a select * from [db].[dbo].[table] LIMIT 0, 10
Otra muestra:
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;
Para mí, el uso de OFFSET y FETCH juntos fue lento, así que usé una combinación de TOP y OFFSET así (que era más rápido):
SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Nota: si utiliza TOP y OFFSET juntos en la misma consulta, como:
SELECT TOP 20 columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS
Luego aparece un error, por lo tanto, para usar TOP y OFFSET juntos, debe separarlo con una subconsulta.
Y si necesita usar SELECT DISTINCT, entonces la consulta es como:
SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Nota: El uso de SELECT ROW_NUMBER con DISTINCT no funcionó para mí.
Puede usar ROW_NUMBER en una Expresión de tabla común para lograr esto.
;WITH My_CTE AS
(
SELECT
col1,
col2,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
SELECT
col1,
col2
FROM
My_CTE
WHERE
row_number BETWEEN @start_row AND @end_row
-- @RowsPerPage can be a fixed number and @PageNumber number can be passed
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 2
SELECT *
FROM MemberEmployeeData
ORDER BY EmployeeNumber
OFFSET @PageNumber*@RowsPerPage ROWS
FETCH NEXT 10 ROWS ONLY
@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
select top (@TakeCount) * --FETCH NEXT
from(
Select ROW_NUMBER() OVER (order by StartDate) AS rowid,*
From YourTable
)A
where Rowid>@SkipCount --OFFSET
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}
Una nota: esta solución solo funcionará en SQL Server 2005 o superior, ya que fue cuando se implementó ROW_NUMBER()
.