seleccionar registros query cierta cantidad sql tsql

query - seleccionar cierta cantidad de registros sql



Cómo obtener N filas comenzando desde la fila M de la tabla ordenada en T-SQL (17)

ACTUALIZACIÓN Si está utilizando SQL 2012, se agregó una nueva sintaxis para que esto sea realmente fácil. Consulte Implementación de la función de búsqueda (omisión / recepción) con esta consulta

Supongo que lo más elegante es usar la función ROW_NUMBER (disponible desde MS SQL Server 2005):

WITH NumberedMyTable AS ( SELECT Id, Value, ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber FROM MyTable ) SELECT Id, Value FROM NumberedMyTable WHERE RowNumber BETWEEN @From AND @To

Hay una manera simple de obtener las N primeras filas de cualquier tabla:

SELECT TOP 10 * FROM MyTable ORDER BY MyColumn

¿Hay alguna forma eficiente de consultar las filas M desde la fila N?

Por ejemplo,

Id Value 1 a 2 b 3 c 4 d 5 e 6 f

Y consultas como esta

SELECT [3,2] * FROM MyTable ORDER BY MyColumn /* hypothetical syntax */

consulta 2 filas comenzando desde la fila 3d, es decir, se devuelven las 4 y 4 filas.


¿Por qué no hacer dos consultas?

select top(M+N-1) * from table into temp tmp_final with no log; select top(N-1) * from tmp_final order by id desc;


A continuación se muestra una consulta simple que enumerará N filas de M + 1ª fila de la tabla. Reemplace M y N con sus números preferidos.

Select Top N B.PrimaryKeyColumn from (SELECT top M PrimaryKeyColumn FROM MyTable ) A right outer join MyTable B on A.PrimaryKeyColumn = B.PrimaryKeyColumn where A.PrimaryKeyColumn IS NULL

Por favor, hágame saber si esto es útil para su situación.


El problema con las sugerencias en este hilo y en otras partes de la web es que todas las soluciones propuestas se ejecutan en tiempo lineal con respecto al número de registros. Por ejemplo, considere una consulta como la siguiente.

select * from ( select Row_Number() over (order by ClusteredIndexField) as RowNumber, * from MyTable ) as PagedTable where RowNumber between @LowestRowNumber and @HighestRowNumber;

Al obtener la página 1, la consulta tarda 0.577 segundos. Sin embargo, al obtener la página 15.619, esta misma consulta toma más de 2 minutos y 55 segundos.

Podemos mejorar esto al crear un número de registro, tabla cruzada de índice como se muestra en la siguiente consulta. La tabla cruzada se llama PagedTable y no es persistente.

select * from ( select Row_Number() over (order by Field1 asc, Field2 asc, Field3 asc) as RowNumber, ClusteredIndexField from MyTable ) as PagedTable left join MyTable on MyTable.ClusteredIndexField = PagedTable.ClusteredIndexField where RowNumber between @LowestRowNumber and @HighestRowNumber;

Como en el ejemplo anterior, probé esto en una tabla muy amplia con 780,928 registros. Usé un tamaño de página de 50, que resultó en 15,619 páginas.

El tiempo total tomado para la página 1 (la primera página) es 0.413 segundos. El tiempo total empleado para la página 15.619 (la última página) es de 0.987 segundos, simplemente el doble de la página 1. Estos tiempos se midieron utilizando SQL Server Profiler y el DBMS fue SQL Server 2008 R2.

Esta solución funciona para cualquier caso cuando clasifique su tabla por índice. El índice no tiene que ser agrupado o simple. En mi caso, el índice estaba compuesto por tres campos: varchar (50) asc, varchar (15) asc, numérico (19,0) asc. Que el rendimiento fue excelente a pesar del engorroso índice demuestra que este enfoque funciona.

Sin embargo, es fundamental que la cláusula order by en la función de ventana Row_Number corresponda a un índice. De lo contrario, el rendimiento se degradará al mismo nivel que el primer ejemplo.

Este enfoque todavía requiere una operación lineal para generar la tabla cruzada no persistente, pero dado que es solo un índice con un número de fila agregado, sucede muy rápidamente. En mi caso, me llevó 0.347 segundos, pero mi caso tenía varcharrs que necesitaban ser copiados. Un solo índice numérico tomaría mucho menos tiempo.

Para todos los propósitos prácticos, este diseño reduce la escala de la paginación del lado del servidor de una operación lineal a una operación logarítmica que permite escalar tablas grandes. A continuación está la solución completa.

-- For a sproc, make these your input parameters declare @PageSize int = 50, @Page int = 15619; -- For a sproc, make these your output parameters declare @RecordCount int = (select count(*) from MyTable); declare @PageCount int = ceiling(convert(float, @RecordCount) / @PageSize); declare @Offset int = (@Page - 1) * @PageSize; declare @LowestRowNumber int = @Offset; declare @HighestRowNumber int = @Offset + @PageSize - 1; select @RecordCount as RecordCount, @PageCount as PageCount, @Offset as Offset, @LowestRowNumber as LowestRowNumber, @HighestRowNumber as HighestRowNumber; select * from ( select Row_Number() over (order by Field1 asc, Field2 asc, Field3 asc) as RowNumber, ClusteredIndexField from MyTable ) as PagedTable left join MyTable on MyTable.ClusteredIndexField = PagedTable.ClusteredIndexField where RowNumber between @LowestRowNumber and @HighestRowNumber;


En SQL 2012 puede usar OFFSET y FETCH :

SELECT * FROM MyTable ORDER BY MyColumn OFFSET @N ROWS FETCH NEXT @M ROWS ONLY; Yo personalmente prefiero:

DECLARE @CurrentSetNumber int = 0; DECLARE @NumRowsInSet int = 2; SELECT * FROM MyTable ORDER BY MyColumn OFFSET @NumRowsInSet * @CurrentSetNumber ROWS FETCH NEXT @NumRowsInSet ROWS ONLY; SET @CurrentSetNumber = @CurrentSetNumber + 1;

donde @NumRowsInSet es el número de filas que desea que se devuelva y @CurrentSetNumber es el número de @NumRowsInSet debe omitir.


Encuentre la identificación para la fila N Luego obtenga las primeras filas M que tienen una identificación mayor o igual a esa

declare @N as int set @N = 2 declare @M as int set @M = 3 declare @Nid as int set @Nid = max(id) from (select top @N * from MyTable order by id) select top @M * from MyTable where id >= @Nid order by id

Algo así ... pero he hecho algunas suposiciones aquí (por ejemplo, quieres pedir por identificación)



Feo, hackish, pero debería funcionar:

select top(M + N - 1) * from TableName except select top(N - 1) * from TableName


Hay un método bastante directo para T-SQL , aunque no estoy seguro si es pre-efectivo si se salta una gran cantidad de filas.

SELECT TOP numberYouWantToTake [yourColumns...] FROM yourTable WHERE yourIDColumn NOT IN ( SELECT TOP numberYouWantToSkip yourIDColumn FROM yourTable ORDER BY yourOrderColumn ) ORDER BY yourOrderColumn

Si usa .Net, puede usar lo siguiente, por ejemplo, un IEnumerable con sus resultados de datos:

IEnumerable<yourDataType> yourSelectedData = yourDataInAnIEnumerable.Skip(nubmerYouWantToSkip).Take(numberYouWantToTake);

Esto tiene la desventaja de que está obteniendo todos los datos del almacenamiento de datos.


Leí todas las respuestas aquí y finalmente encontré una solución utilizable que es simple. Los problemas de rendimiento surgen de la declaración BETWEEN, no de la generación de los números de filas. Así que utilicé un algoritmo para hacer paginación dinámica pasando el número de página y el número de registros.

Los pases no son fila de inicio y número de filas, sino "filas por página (500)" y "número de página (4)", que serían las filas 1501 - 2000. Estos valores pueden reemplazarse por variables de procedimiento almacenadas para que no bloqueado en el uso de una cantidad de paginación específica.

select * from ( select (((ROW_NUMBER() OVER(ORDER BY MyField) - 1) / 500) + 1) AS PageNum , * from MyTable ) as PagedTable where PageNum = 4;


Para hacer esto en SQL Server, debe ordenar la consulta por una columna, para que pueda especificar las filas que desea.

No puede usar la palabra clave "TOP" al hacer esto, debe usar N filas de compensación para obtener las próximas M filas.

Ejemplo:

select * from table order by [some_column] offset 10 rows FETCH NEXT 10 rows only

Puede obtener más información aquí: https://technet.microsoft.com/pt-br/library/gg699618%28v=sql.110%29.aspx


Probablemente bueno para pequeños resultados, funciona en todas las versiones de TSQL:

SELECT * FROM (SELECT TOP (N) * FROM (SELECT TOP (M + N - 1) FROM Table ORDER BY MyColumn) qasc ORDER BY MyColumn DESC) qdesc ORDER BY MyColumn


Si desea seleccionar 100 registros del 25 ° registro:

select TOP 100 * from TableName where PrimaryKeyField NOT IN(Select TOP 24 PrimaryKeyField from TableName);


Y así es como puede lograr el mismo objetivo en tablas sin clave principal:

select * from ( select row_number() over(order by (select 0)) rowNum,* from your_table ) tmp where tmp.rowNum between 20 and 30 -- any numbers you need


-- *some* implementations may support this syntax (mysql?) SELECT Id,Value FROM xxx ORDER BY Id LIMIT 2 , 0 ; -- Separate LIMIT, OFFSET SELECT Id,Value FROM xxx ORDER BY Id LIMIT 2 OFFSET 2 ; -- SQL-2008 syntax SELECT Id,Value FROM xxx ORDER BY Id OFFSET 4 FETCH NEXT 2 ROWS ONLY ;


@start = 3 @records = 2 Select ID, Value From (SELECT ROW_NUMBER() OVER(ORDER BY ID) AS RowNum, ID,Value From MyTable) as sub Where sub.RowNum between @start and @start+@records

Esta es una forma. hay muchos otros si busca en Google SQL Paging.


SELECT * FROM ( SELECT Row_Number() Over (Order by (Select 1)) as RawKey, * FROM [Alzh].[dbo].[DM_THD_TRANS_FY14] ) AS foo WHERE RawKey between 17210400 and 17210500