Comment mettre en œuvre LIMIT avec Microsoft SQL Server?
j'ai cette requête avec mysql:
select * from table1 LIMIT 10,20
Comment puis-je faire cela avec Microsoft sql ?
14 réponses
démarrer 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 suivantes...
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 de limitation est criminelle, IMO. Vous ne devriez pas avoir à faire ce genre 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 par n'est pas unique.
si la requête est modifiée à L'ordre Par OrderDate, le jeu de résultats retourné n'est pas comme prévu.
c'est presque une réplique d'une question que j'ai posée en octobre: Emulate MySQL LIMIT clause in 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 à capturer le résultat de la requête dans une table temporaire avec une IDENTITY
clé primaire. Ensuite, interrogez la colonne de la clé primaire en utilisant la condition BETWEEN
.
si vous utilisez Microsoft SQL Server 2005 ou plus tard, vous avez une fonction ROW_NUMBER()
, donc vous pouvez 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 aussi écrire ceci comme une expression courante de table comme montré dans réponse 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
C'est comme ça que je limite les résultats dans MS SQL Server 2012
SELECT *
FROM table1
ORDER BY columnName
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
NOTE: L'OFFSET ne peut être utilisé qu'avec ou en tandem sur commande.
pour expliquer le décalage de la ligne de code xx ROWS FETCH NEXT yy ROW ONLY
le " xx " est le nombre d'enregistrement / ligne que vous voulez commencer à tirer dans le tableau.
IE: s'il y a 40 mentions dans le tableau 1. Le code ci-dessus commencera à sortir de la rangée 10.
le" yy " est le nombre d'enregistrements / lignes que vous voulez tirer de la table.
à partir de l'exemple précédent.
IE: si le tableau 1 contient 40 enregistrements et que vous avez commencé à tirer de la rangée 10 et à saisir l'ensemble suivant de 10 (yy).
cela signifierait que le code ci-dessus retirera les enregistrements du tableau 1 à partir de la rangée 10 et se terminant à 20. Tirant ainsi les rangées 10-20.
consultez le lien pour plus d'informations sur OFFSET
syntactically MySQL LIMIT query est quelque chose comme ceci:
SELECT * FROM table LIMIT OFFSET, ROW_COUNT
cela 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 tout simplement pas une 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
alors il suffit de demander:
SELECT * FROM v_table WHERE row BETWEEN 10 AND 20
si des champs sont ajoutés ou supprimés," ligne " est mis à jour automatiquement.
le principal problème avec cette option est que L'ordre Par est fixe. Donc si vous voulez un ordre différent, vous devez créer une autre vue.
mise à 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
où devient limité aux données qui sont dans les lignes entre 10 et 20 (au lieu de rechercher l'ensemble des données et de limiter la sortie).
il s'agit d'une approche en plusieurs étapes qui fonctionnera dans 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
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;
dans SQL il n'y a pas de mot-clé LIMIT existe. Si vous n'avez besoin que d'un nombre limité de lignes, vous devez utiliser un mot-clé supérieur qui est similaire à une limite.
doit essayer. Dans la requête ci-dessous, vous pouvez voir group by, order by, Skip rows, et limit rows.
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 je me souviens bien (ça fait longtemps que je N'ai pas utilisé SQL Server), vous pourriez 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
SELECT TOP 10 * FROM table;
est le même que
SELECT * FROM table LIMIT 0,10;
voici un article sur la limite de mise en œuvre dans MsSQL C'est une lecture agréable, spécialement les commentaires.