Eu tenho essa consulta com o MySQL:
select * from table1 LIMIT 10,20
Como posso fazer isso com o SQL Server?
Eu tenho essa consulta com o MySQL:
select * from table1 LIMIT 10,20
Como posso fazer isso com o SQL Server?
Respostas:
Iniciando o SQL SERVER 2005, você pode fazer isso ...
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;
ou algo assim para as versões 2000 e inferiores ...
SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC
Desajeitado, mas vai funcionar.
SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id
A omissão do MSSQL de uma cláusula LIMIT é criminal, IMO. Você não deveria ter que fazer esse tipo de solução alternativa.
A partir do SQL SERVER 2012, você pode usar a 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
Isso pode não funcionar corretamente quando a ordem de não é exclusiva.
Se a consulta for modificada para ORDER BY OrderDate, o conjunto de resultados retornado não será o esperado.
Isso é quase uma duplicata de uma pergunta que fiz em outubro: Emular a cláusula MySQL LIMIT no Microsoft SQL Server 2000
Se você estiver usando o Microsoft SQL Server 2000, não há uma boa solução. A maioria das pessoas precisa recorrer à captura do resultado da consulta em uma tabela temporária com uma IDENTITY
chave primária. Em seguida, consulte a coluna da chave primária usando uma BETWEEN
condição.
Se você estiver usando o Microsoft SQL Server 2005 ou posterior, terá uma ROW_NUMBER()
função, para obter o mesmo resultado, mas evite a tabela temporária.
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;
Você também pode escrever isso como uma expressão de tabela comum, como mostra a resposta de @Leon Tayson .
É assim que limito os resultados no MS SQL Server 2012:
SELECT *
FROM table1
ORDER BY columnName
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
NOTA: OFFSET
só pode ser usado com ou em conjunto com ORDER BY
.
Para explicar a linha de código OFFSET xx ROWS FETCH NEXT yy ROW ONLY
A xx
é o número de registro / linha que deseja começar a puxar a partir da tabela, ou seja: se houver 40 registros na tabela 1, o código acima irá começar a puxar da linha 10.
O yy
é o número de registros / linhas que você deseja extrair da tabela.
Para desenvolver o exemplo anterior: Se a tabela 1 possui 40 registros e você começou a puxar da linha 10 e pegue o conjunto NEXT de 10 ( yy
). Isso significa que o código acima extrairá os registros da tabela 1, iniciando na linha 10 e terminando em 20. Assim, extrair as linhas 10 - 20.
Confira o link para obter mais informações sobre OFFSET
SELECT *
FROM (
SELECT TOP 20
t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
FROM table1 t
ORDER BY
field1
) t
WHERE rn > 10
A consulta Sintatisticamente MySQL LIMIT é algo como isto:
SELECT * FROM table LIMIT OFFSET, ROW_COUNT
Isso pode ser traduzido para o 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
Agora sua consulta select * from table1 LIMIT 10,20
será assim:
SELECT * FROM
(
SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum
FROM table1
) a
WHERE rnum > 10
Esta é uma das razões pelas quais tento evitar o uso do MS Server ... mas mesmo assim. Às vezes você simplesmente não tem uma opção (yei! E eu tenho que usar uma versão desatualizada !!).
Minha sugestão é criar uma tabela virtual:
De:
SELECT * FROM table
Para:
CREATE VIEW v_table AS
SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table
Em seguida, basta consultar:
SELECT * FROM v_table WHERE row BETWEEN 10 AND 20
Se os campos forem adicionados ou removidos, "linha" é atualizada automaticamente.
O principal problema com esta opção é que ORDER BY foi corrigido. Portanto, se você quiser uma ordem diferente, precisará criar outra exibição.
ATUALIZAR
Há outro problema com essa abordagem: se você tentar filtrar seus dados, eles não funcionarão conforme o esperado. Por exemplo, se você fizer:
SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20
WHERE fica limitado aos dados que estão nas linhas entre 10 e 20 (em vez de pesquisar todo o conjunto de dados e limitar a saída).
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;
Deve tentar. Na consulta abaixo, você pode ver agrupar, ordenar, Ignorar linhas e limitar linhas.
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
SELECT TOP 10 * FROM table;
É o mesmo que
SELECT * FROM table LIMIT 0,10;
Aqui está um artigo sobre a implementação do Limit no MsSQL. É uma boa leitura, especialmente os comentários.
No SQL, não existe uma palavra-chave LIMIT. Se você precisar apenas de um número limitado de linhas, use uma palavra-chave TOP que seja semelhante a um LIMIT.
Se seu ID for do tipo identificador único ou se não for classificado na tabela, faça o seguinte abaixo.
select * from
(select ROW_NUMBER() OVER (ORDER BY (select 0)) AS RowNumber,* from table1) a
where a.RowNumber between 2 and 5
O código será
selecione * do limite 2,5
melhor usar isso no MSSQLExpress 2017.
SELECT * FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;
--Dando a uma coluna [Count] e atribuindo a cada linha uma contagem única sem solicitar algo e selecione novamente onde você pode fornecer seus limites .. :)
Uma das maneiras possíveis de obter resultados como abaixo, espero que isso ajude.
declare @start int
declare @end int
SET @start = '5000'; -- 0 , 5000 ,
SET @end = '10000'; -- 5001, 10001
SELECT * FROM (
SELECT TABLE_NAME,TABLE_TYPE, ROW_NUMBER() OVER (ORDER BY TABLE_NAME) as row FROM information_schema.tables
) a WHERE a.row > @start and a.row <= @end
Se bem me lembro (já faz um tempo desde que me envolvi com o SQL Server), talvez você possa usar algo assim: (2005 e posteriores)
SELECT
*
,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
WHERE
um alias definido na mesma SELECT
cláusula de nível .