En PostgreSQL existen las palabras clave 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?
En PostgreSQL existen las palabras clave 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?
Respuestas:
El equivalente de LIMIT
es SET ROWCOUNT
, pero si desea 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 del desplazamiento y el límite en caso de que decida cambiar sus opciones de paginación (o permitir que el usuario lo haga).
Nota: el @Offset
parámetro debe usar una indexación basada en uno para esto en lugar de la indexación normal basada en cero.
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
tiene 200k registros, primero buscará todos y luego aplicará el límite. ¿Es eficiente esta consulta?
Esta característica ahora se simplifica en SQL Server 2012. Esto funciona desde SQL Server 2012 en adelante.
Límite con desplazamiento para seleccionar 11 a 20 filas en 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 filas omitidasNEXT
: número requerido de filas siguientesReferencia: https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017
SQL_CALC_FOUND_ROWS
cuando se usa esto?
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 esto fue cuando ROW_NUMBER()
se implementó.
AS xx
Para mí, el uso de OFFSET y FETCH juntos fue lento, por lo que utilicé una combinación de TOP y OFFSET como esta (que fue más rápido):
SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Nota: Si usa 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 obtiene un error, por lo que para usar TOP y OFFSET juntos debe separarlo con una subconsulta.
Y si necesita usar SELECT DISTINCT, 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í.
SELECT TOP 20 id FROM table1 where id > 10 order by date OFFSET 20 rows
, debe transformarlo como SELECT TOP 20 * FROM (SELECT id FROM table1 where id > 10 order by date OFFSET 20 ROWS) t1
. Editaré mi respuesta. Gracias y disculpa mi inglés.
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;
Hay aquí alguien que le dice acerca de esta característica en SQL 2011, es triste que elijan un poco de la palabra llave "OFFSET / FETCH" pero no es standart que bien.
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 la página (@PageSize). De esta manera, 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
Lo más cerca que puedo hacer es
select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber
Que supongo que es similar a select * from [db].[dbo].[table] LIMIT 0, 10
-- @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
Como 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:
@limit
se puede reemplazar con varios resultados para recuperar,@offset
es el número de resultados para omitirwhere
y order by
cláusulas, y proporcionará resultados incorrectos si no están sincronizadosorder by
está ahí explícitamente si eso es lo que se necesita?Específicamente para SQL-SERVER, puede lograrlo de muchas maneras diferentes. Para un ejemplo real, tomamos la tabla Cliente aquí.
Ejemplo 1: con "SET ROWCOUNT"
SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Para devolver todas las filas, establezca ROWCOUNT en 0
SET ROWCOUNT 0
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Ejemplo 2: con "ROW_NUMBER y 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
Ejemplo 3: con "OFFSET y FETCH", pero con este "ORDER BY" es obligatorio
SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
Espero que esto te ayude.
Desde entonces, pruebo más veces este script más útil en 1 millón de registros cada página. 100 registros con paginación funcionan más rápido. Mi PC ejecuta este script 0 segundos mientras lo comparo con mysql tiene su propio límite y compensa aproximadamente 4.5 segundos para obtener el resultado.
Alguien puede perder de entender Row_Number () siempre ordenar por campo específico. En caso de que necesitemos definir solo una fila en secuencia, debemos 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}
Explique: