¿Cómo implementar LIMIT con Microsoft SQL Server?


Tengo esta consulta con mysql:

select * from table1 LIMIT 10,20

¿Cómo puedo hacer esto con Microsoft sql?

Author: Abdulla Nilam, 2009-03-02

14 answers

A partir de SQL SERVER 2005, puede hacer esto...

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 10 AND 20;

O algo así para las versiones 2000 y siguientes...

SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC
 100
Author: Leon Tayson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-02 20:07:04

Torpe, pero funcionará.

SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id

La omisión de MSSQL de una cláusula LÍMITE es criminal, IMO. No deberías tener que hacer este tipo de solución kludgy.

 44
Author: ceejayoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-02 19:58:12

A partir de SQL SERVER 2012, puede usar la cláusula OFFSET FETCH:

USE AdventureWorks;
GO
SELECT SalesOrderID, OrderDate
FROM Sales.SalesOrderHeader 
ORDER BY SalesOrderID
    OFFSET 10 ROWS
    FETCH NEXT 10 ROWS ONLY;
GO

Http://msdn.microsoft.com/en-us/library/ms188385 (v = sql.110).aspx

Esto puede no funcionar correctamente cuando el order by no es único.

Si la consulta se modifica a ORDER BY OrderDate, el conjunto de resultados devuelto no es el esperado.

 22
Author: user4047259,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-16 16:37:33

Esto es casi un duplicado de una pregunta que hice en octubre: Emular la cláusula de LÍMITE de MySQL en Microsoft SQL Server 2000

Si está utilizando Microsoft SQL Server 2000, no hay una buena solución. La mayoría de las personas tienen que recurrir a capturar el resultado de la consulta en una tabla temporal con una clave primaria IDENTITY. Luego consulta contra la columna de clave primaria usando una condición BETWEEN.

Si está utilizando Microsoft SQL Server 2005 o posterior, tiene una función ROW_NUMBER(), por lo que puede obtenga el mismo resultado, pero evite la tabla temporal.

SELECT t1.*
FROM (
    SELECT ROW_NUMBER OVER(ORDER BY id) AS row, t1.*
    FROM ( ...original SQL query... ) t1
) t2
WHERE t2.row BETWEEN @offset+1 AND @offset+@count;

También puede escribir esto como una expresión común de tabla como se muestra en la respuesta de @Leon Tayson.

 18
Author: Bill Karwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:33:16
SELECT  *
FROM    (
        SELECT  TOP 20
                t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
        FROM    table1 t
        ORDER BY
                field1
        ) t
WHERE   rn > 10
 12
Author: Quassnoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-25 07:49:31

Así es como limito los resultados en MS SQL Server 2012

SELECT * 
FROM table1
ORDER BY columnName
  OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

NOTA: El DESPLAZAMIENTO solo se puede usar con o en tándem para ORDENAR POR.

Para explicar el DESPLAZAMIENTO de la línea de código las FILAS xx OBTIENEN LA SIGUIENTE FILA yy SOLO

El "xx" es el número de registro / fila del que desea comenzar a extraer en la tabla.
IE: Si hay 40 registro en la tabla 1. El código anterior comenzará a tirar de la fila 10.

El "yy" es el número de registros / filas que desea extraer de la tabla.
Para construir sobre el ejemplo anterior.
IE: Si la tabla 1 tiene 40 registros y comenzó a tirar de la fila 10 y agarrar el SIGUIENTE conjunto de 10 (aa).
Eso significaría que el código anterior extraerá los registros de la tabla 1 comenzando en la fila 10 y terminando en 20. Tirando así las series 10-20.

Echa un vistazo al enlace para obtener más información sobre OFFSET

 9
Author: Jeremy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-21 20:56:32

Sintácticamente MySQL LIMIT query es algo como esto:

SELECT * FROM table LIMIT OFFSET, ROW_COUNT

Esto se puede traducir a Microsoft SQL Server como

SELECT * FROM 
(
    SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table
) a
WHERE rnum > OFFSET

Ahora su consulta select * from table1 LIMIT 10,20 será así:

SELECT * FROM 
(
    SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table1
) a
WHERE rnum > 10 
 8
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-06 12:25:17

Esta es una de las razones por las que intento evitar el uso de MS Server... pero de todos modos. A veces simplemente no tienes una opción (yei! y tengo que usar una versión antigua!!).

Mi sugerencia es crear una tabla virtual:

De:

SELECT * FROM table

A:

CREATE VIEW v_table AS    
    SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table

Entonces solo pregunta:

SELECT * FROM v_table WHERE row BETWEEN 10 AND 20

Si se agregan o eliminan campos, "row" se actualiza automáticamente.

El principal problema con esta opción es que ORDER BY está arreglado. Así que si quieres un orden diferente, lo harías tienes que crear otra vista.

UPDATE

Hay otro problema con este enfoque: si intenta filtrar sus datos, no funcionará como se esperaba. Por ejemplo, si lo hace:

SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20

DONDE se limita a los datos que están en las filas entre 10 y 20 (en lugar de buscar todo el conjunto de datos y limitar la salida).

 2
Author: lepe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-17 04:22:49

Este es un enfoque de varios pasos que funcionará en SQL2000.

-- Create a temp table to hold the data
CREATE TABLE #foo(rowID int identity(1, 1), myOtherColumns)

INSERT INTO #foo (myColumns) SELECT myData order By MyCriteria

Select * FROM #foo where rowID > 10
 1
Author: souLTower,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-02 20:18:10
SELECT 
    * 
FROM 
    (
        SELECT 
            top 20              -- ($a) number of records to show
            * 
        FROM
            (
                SELECT 
                    top 29      -- ($b) last record position
                    * 
                FROM 
                    table       -- replace this for table name (i.e. "Customer")
                ORDER BY 
                    2 ASC
            ) AS tbl1 
        ORDER BY 
            2 DESC
    ) AS tbl2 
ORDER BY 
    2 ASC;

-- Examples:

-- Show 5 records from position 5:
-- $a = 5;
-- $b = (5 + 5) - 1
-- $b = 9;

-- Show 10 records from position 4:
-- $a = 10;
-- $b = (10 + 4) - 1
-- $b = 13;

-- To calculate $b:
-- $b = ($a + position) - 1

-- For the present exercise we need to:
-- Show 20 records from position 10:
-- $a = 20;
-- $b = (20 + 10) - 1
-- $b = 29;
 1
Author: Julian Moreno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-28 15:28:12

En SQL no existe ninguna palabra clave LIMIT. Si solo necesita un número limitado de filas, debe usar una palabra clave SUPERIOR que sea similar a un LÍMITE.

 0
Author: Mitul Panchal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-23 05:04:40

Debe intentarlo. En la siguiente consulta, puede ver agrupar por, ordenar por, Saltar filas y limitar filas.

select emp_no , sum(salary_amount) from emp_salary
Group by emp_no 
ORDER BY emp_no 
OFFSET 5 ROWS       -- Skip first 5 
FETCH NEXT 10 ROWS ONLY; -- limit to retrieve next 10 row after skiping rows
 0
Author: M Danish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-12 11:21:31

Si no recuerdo mal (ha pasado un tiempo desde que hice un dabbed con SQL Server) puede ser capaz de usar algo como esto: (2005 y arriba)

SELECT
    *
   ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
 -2
Author: Kris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-02 20:02:12
SELECT TOP 10 * FROM table;

Es lo mismo que

SELECT * FROM table LIMIT 0,10;

Aquí hay un artículo sobre la implementación de Límite en MsSQL Es una buena lectura, especialmente los comentarios.

 -5
Author: Ólafur Waage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-03-02 19:56:34