J'ai cette requête avec MySQL:
select * from table1 LIMIT 10,20
Comment puis-je faire cela avec SQL Server?
J'ai cette requête avec MySQL:
select * from table1 LIMIT 10,20
Comment puis-je faire cela avec SQL Server?
Réponses:
À partir de SQL SERVER 2005, vous pouvez le faire ...
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 quelque chose comme ça pour les versions 2000 et inférieures ...
SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC
Clunky, mais ça marchera.
SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id
L'omission par MSSQL d'une clause LIMIT est criminelle, IMO. Vous ne devriez pas avoir à faire ce genre de solution de contournement kludgy.
À partir de SQL SERVER 2012, vous pouvez utiliser la clause 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
Cela peut ne pas fonctionner correctement lorsque la commande par n'est pas unique.
Si la requête est modifiée en ORDER BY OrderDate, le jeu de résultats renvoyé n'est pas celui attendu.
C'est presque le double d'une question que j'ai posée en octobre: émuler la clause MySQL LIMIT dans Microsoft SQL Server 2000
Si vous utilisez Microsoft SQL Server 2000, il n'y a pas de bonne solution. La plupart des gens doivent recourir à la capture du résultat de la requête dans une table temporaire avec une IDENTITY
clé primaire. Puis interrogez la colonne de clé primaire à l'aide d'unBETWEEN
condition.
Si vous utilisez Microsoft SQL Server 2005 ou une version ultérieure, vous disposez d'une ROW_NUMBER()
fonction, vous pouvez donc obtenir le même résultat, mais évitez la table temporaire.
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;
Vous pouvez également l'écrire comme une expression de table commune comme indiqué dans la réponse de @Leon Tayson .
Voici comment je limite les résultats dans MS SQL Server 2012:
SELECT *
FROM table1
ORDER BY columnName
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
REMARQUE: OFFSET
ne peut être utilisé qu'avec ou en tandem pourORDER BY
.
Pour expliquer la ligne de code OFFSET xx ROWS FETCH NEXT yy ROW ONLY
le xx
est le numéro d'enregistrement / de ligne à partir duquel vous souhaitez commencer à extraire dans la table, c'est-à-dire: S'il y a 40 enregistrements dans le tableau 1, le code ci-dessus commencera à extraire à partir de la ligne 10.
le yy
est le nombre d'enregistrements / lignes que vous souhaitez extraire de la table.
Pour construire sur l'exemple précédent: Si la table 1 contient 40 enregistrements et que vous avez commencé à extraire de la ligne 10 et à saisir l'ensemble NEXT de 10 (yy
). Cela signifierait que le code ci-dessus extraira les enregistrements de la table 1 à partir de la ligne 10 et se terminant à 20. Tirant ainsi les lignes 10 à 20.
Consultez le lien pour plus d'informations sur 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
Syntaxiquement, la requête MySQL LIMIT est quelque chose comme ceci:
SELECT * FROM table LIMIT OFFSET, ROW_COUNT
Cela peut être traduit dans Microsoft SQL Server comme
SELECT * FROM
(
SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum
FROM table
) a
WHERE rnum > OFFSET
Maintenant, votre requête select * from table1 LIMIT 10,20
sera comme ceci:
SELECT * FROM
(
SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum
FROM table1
) a
WHERE rnum > 10
C'est l'une des raisons pour lesquelles j'essaie d'éviter d'utiliser MS Server ... mais quand même. Parfois, vous n'avez tout simplement pas d'option (yei! Et je dois utiliser une version obsolète !!).
Ma suggestion est de créer une table virtuelle:
De:
SELECT * FROM table
À:
CREATE VIEW v_table AS
SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table
Ensuite, interrogez simplement:
SELECT * FROM v_table WHERE row BETWEEN 10 AND 20
Si des champs sont ajoutés ou supprimés, la "ligne" est mise à jour automatiquement.
Le principal problème avec cette option est que ORDER BY est résolu. Donc, si vous voulez un ordre différent, vous devrez créer une autre vue.
METTRE À JOUR
Il y a un autre problème avec cette approche: si vous essayez de filtrer vos données, cela ne fonctionnera pas comme prévu. Par exemple, si vous faites:
SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20
WHERE devient limité aux données qui sont dans les lignes entre 10 et 20 (au lieu de rechercher l'ensemble de données et de limiter la sortie).
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;
Dois essayer. Dans la requête ci-dessous, vous pouvez voir le groupe par, l'ordre par, ignorer les lignes et limiter les lignes.
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;
Est le même que
SELECT * FROM table LIMIT 0,10;
Voici un article sur l'implémentation de Limit dans MsSQL C'est une bonne lecture, spécialement les commentaires.
En SQL, il n'existe pas de mot clé LIMIT. Si vous n'avez besoin que d'un nombre limité de lignes, vous devez utiliser un mot-clé TOP similaire à LIMIT.
Si votre identifiant est de type identifiant unique ou que votre identifiant dans la table n'est pas trié, vous devez procéder comme suit.
select * from
(select ROW_NUMBER() OVER (ORDER BY (select 0)) AS RowNumber,* from table1) a
where a.RowNumber between 2 and 5
Le code sera
sélectionner * à partir de la limite 2,5
mieux utiliser cela dans MSSQLExpress 2017.
SELECT * FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;
--Donner une colonne [Count] et attribuer à chaque ligne un comptage unique sans ordonner quelque chose, puis re-sélectionner où vous pouvez fournir vos limites .. :)
L'un des moyens possibles d'obtenir le résultat ci-dessous, espérons que cela vous aidera.
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
Si je me souviens bien (cela fait un moment que je n'ai pas utilisé SQL Server), vous pourrez peut-être utiliser quelque chose comme ceci: (2005 et plus)
SELECT
*
,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
WHERE
un alias défini dans la même SELECT
clause de niveau .