J'ai cette requête avec mysql:
select * from table1 LIMIT 10,20
Comment puis-je faire cela avec Microsoft SQL?
À 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 va marcher.
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.
À 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 de 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 une copie d’une question que j’avais posée en octobre: Emulate MySQL LIMIT clause 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 capturer le résultat de la requête dans une table temporaire avec une clé primaire IDENTITY
. Interrogez ensuite la colonne de clé primaire en utilisant une condition BETWEEN
.
Si vous utilisez Microsoft SQL Server 2005 ou une version ultérieure, vous disposez d'une fonction ROW_NUMBER()
. Vous pouvez ainsi obtenir le même résultat mais éviter 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 écrire ceci sous la forme d'une expression de table common , comme indiqué dans le answer de @Leon Tayson.
SELECT *
FROM (
SELECT TOP 20
t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
FROM table1 t
ORDER BY
field1
) t
WHERE rn > 10
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 ORDER BY.
Pour expliquer la ligne de code OFFSET xx ROWS FETCH NEY yy ROW ONLY
Le "xx" est le numéro d'enregistrement/ligne que vous voulez commencer à extraire dans la table .
IE: S'il y a 40 enregistrements dans la table 1. Le code ci-dessus commencera à extraire de la ligne 10.
Le "yy" est le nombre d'enregistrements/lignes que vous voulez extraire de la table .
Pour construire sur l'exemple précédent.
IE: Si la table 1 contient 40 enregistrements et que vous avez commencé à extraire de la ligne 10, vous avez saisi l'ensemble NEXT de 10 (yy).
Cela signifie que le code ci-dessus extraira les enregistrements de la table 1 en commençant par la ligne 10 et en finissant par 20. Ainsi, en extrayant les lignes 10 à 20.
Consultez le lien pour plus d'informations sur OFFSET
Syntaxiquement, la requête MySQL LIMIT ressemble à ceci:
SELECT * FROM table LIMIT OFFSET, ROW_COUNT
Ceci peut être traduit en 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 de toute façon. Parfois, vous n'avez 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, il suffit d'interroger:
SELECT * FROM v_table WHERE row BETWEEN 10 AND 20
Si des champs sont ajoutés ou supprimés, "row" est mis à jour automatiquement.
Le principal problème de cette option est que ORDER BY est corrigé. Donc, si vous voulez un ordre différent, vous devrez créer une autre vue.
METTRE À JOUR
Il existe 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 le faites:
SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20
WHERE devient limité aux données contenues dans les lignes comprises entre 10 et 20 (au lieu de rechercher l'ensemble du jeu 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;
Il s’agit d’une approche en plusieurs étapes qui fonctionnera sous 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
mieux l'utiliser 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 rien commander, puis sélectionner à nouveau où vous pouvez indiquer vos limites .. :)
En SQL, il n'y a 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 à un mot LIMIT.
Dois essayer. Dans la requête ci-dessous, vous pouvez voir group by, order by, Ignorer les lignes et les limiter.
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
Si votre identifiant est un identifiant unique ou si votre identifiant dans la table n'est pas trié, procédez 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électionnez * de la limite 2,5