TOP (Transact-SQL)
S’applique à :SQL ServerBase de données Azure SQLAzure SQL Managed InstanceAzure Synapse AnalyticsAnalytics Platform System (PDW)Point de terminaison d'analyse SQL dans Microsoft FabricEntrepôt dans Microsoft FabricBase de données SQL dans Microsoft Fabric
Limite les lignes retournées dans un jeu de résultats de la requête à un nombre spécifié de lignes ou à un pourcentage de lignes dans SQL Server. Lorsque vous utilisez TOP
avec la clause ORDER BY
, le jeu de résultats est limité au premier n nombre de lignes ordonnées. Sinon, TOP
retourne le premier n nombre de lignes dans un ordre non défini. Utilisez cette clause pour spécifier le nombre de lignes retournées à partir d’une instruction SELECT
. Vous pouvez également utiliser TOP
pour spécifier les lignes affectées par une instruction INSERT
, UPDATE
, MERGE
ou DELETE
.
Conventions de la syntaxe Transact-SQL
Syntaxe
Syntaxe pour SQL Server et Azure SQL Database :
[
TOP (expression) [ PERCENT ]
[ WITH TIES ]
]
Syntaxe pour azure Synapse Analytics and Analytics Platform System (PDW) :
[
TOP ( expression )
[ WITH TIES ]
]
Arguments
expression
Expression numérique qui définit le nombre de lignes à renvoyer.
PERCENT
Indique que la requête retourne seulement les premiers expression % des lignes du jeu de résultats. Les valeurs fractionnaires sont arrondies à la valeur entière suivante.
WITH TIES
Retourne au moins deux lignes liées au dernier emplacement dans le jeu de résultats limité. Vous devez utiliser cet argument avec la clause ORDER BY
.
WITH TIES
peut renvoyer plus de lignes que la valeur spécifiée dans expression. Par exemple, si expression est définie sur 5
mais que deux lignes supplémentaires correspondent aux valeurs des colonnes ORDER BY
dans la ligne 5, le jeu de résultats contient sept lignes.
Vous pouvez spécifier la clause TOP
avec l’argument WITH TIES
uniquement dans les instructions SELECT
, et uniquement si vous spécifiez également la clause ORDER BY
. L'ordre retourné pour la liaison des enregistrements est arbitraire.
ORDER BY
n’affecte pas cette règle.
Meilleures pratiques
Dans une instruction SELECT
, utilisez toujours une clause ORDER BY
avec la clause TOP
. Il s’agit de la seule façon d’indiquer de manière prévisible les lignes affectées par TOP
.
Utilisez OFFSET
et FETCH
dans la clause ORDER BY
au lieu de la clause TOP
pour implémenter une solution de pagination de requête. Une solution de pagination (autrement dit, l’envoi de blocs ou de pages de données au client) est plus facile à implémenter à l’aide de OFFSET
et de clauses FETCH
. Pour plus d’informations, consultez clause SELECT - ORDER BY.
Utilisez TOP
(ou OFFSET
et FETCH
) au lieu de SET ROWCOUNT
pour limiter le nombre de lignes retournées. Ces méthodes sont préférées à l’utilisation de SET ROWCOUNT
pour les raisons suivantes :
- Dans le cadre d’une instruction
SELECT
, l’optimiseur de requête peut prendre en compte la valeur de expression dans les clausesTOP
ouFETCH
lors de l’optimisation des requêtes. Étant donné que vous utilisezSET ROWCOUNT
en dehors d’une instruction qui exécute une requête, sa valeur ne peut pas être considérée dans un plan de requête.
Prise en charge de la compatibilité
Pour la compatibilité descendante, les parenthèses sont facultatives dans les instructions SELECT
si l’expression est une constante entière. Nous vous recommandons d’utiliser toujours des parenthèses pour TOP
dans les instructions SELECT
. Cela fournit une cohérence avec son utilisation requise dans les instructions INSERT
, UPDATE
, MERGE
et DELETE
.
Interopérabilité
L’expression TOP
n’affecte pas les instructions qui peuvent s’exécuter en raison d’un déclencheur. Les tables inserted
et deleted
dans les déclencheurs retournent uniquement les lignes réellement affectées par les instructions INSERT
, UPDATE
, MERGE
ou DELETE
. Par exemple, si une INSERT TRIGGER
se déclenche à la suite d’une instruction INSERT
qui a utilisé une clause TOP
.
SQL Server tient compte de la mise à jour de lignes via des vues. Étant donné que vous pouvez inclure la clause TOP
dans la définition d’affichage, certaines lignes peuvent disparaître de la vue si les lignes ne répondent plus aux exigences de l’expression TOP
en raison d’une mise à jour.
Lorsqu’elle est spécifiée dans l’instruction MERGE
, la clause TOP
s’applique après la table source entière et la table cible entière est jointe. Les lignes jointes non éligibles à une action INSERT, UPDATE ou DELETE sont supprimées. La clause TOP
réduit davantage le nombre de lignes jointes à la valeur spécifiée et les actions d’insertion, de mise à jour ou de suppression s’appliquent aux lignes jointes restantes de manière non ordonnée. Autrement dit, il n’existe aucun ordre dans lequel les lignes sont distribuées entre les actions définies dans les clauses WHEN
. Par exemple, si la spécification de TOP (10)
affecte 10 lignes, sept de ces lignes peuvent être mises à jour et trois insérées. Ou bien, un peut être supprimé, cinq mis à jour et quatre insérés, et ainsi de suite. Étant donné que l’instruction MERGE
effectue une analyse complète de table des tables sources et cibles, les performances d’E/S peuvent être affectées lorsque vous utilisez la clause TOP
pour modifier une table volumineuse en créant plusieurs lots. Dans ce scénario, il est important de s’assurer que tous les lots consécutifs ciblent les nouvelles lignes.
Soyez prudent lorsque vous spécifiez la clause TOP
dans une requête qui contient un UNION
, UNION ALL
, EXCEPT
ou un opérateur INTERSECT
. Il est possible d’écrire une requête qui retourne des résultats inattendus, car l’ordre dans lequel les clauses TOP
et ORDER BY
sont traitées logiquement n’est pas toujours intuitive lorsque ces opérateurs sont utilisés dans une opération de sélection. Par exemple, d'après le tableau et les données qui suivent, supposez que vous souhaitez renvoyer la voiture rouge la moins chère et la voiture bleue la moins chère. Autrement dit, la berline rouge et le fourgon bleu.
CREATE TABLE dbo.Cars
(
Model VARCHAR (15),
Price MONEY,
Color VARCHAR (10)
);
INSERT dbo.Cars
VALUES ('sedan', 10000, 'red'),
('convertible', 15000, 'blue'),
('coupe', 20000, 'red'),
('van', 8000, 'blue');
Pour obtenir ces résultats, vous pouvez écrire la requête suivante.
SELECT TOP (1) Model, Color, Price
FROM dbo.Cars
WHERE Color = 'red'
UNION ALL
SELECT TOP (1) Model, Color, Price
FROM dbo.Cars
WHERE Color = 'blue'
ORDER BY Price ASC;
GO
Voici le jeu de résultats.
Model Color Price
------------- ---------- -------
sedan red 10000.00
convertible blue 15000.00
Les résultats inattendus sont retournés, car la clause TOP
s’exécute logiquement avant la clause ORDER BY
, qui trie les résultats de l’opérateur (UNION ALL
dans ce cas). Par conséquent, la requête précédente retourne toute voiture rouge et toute voiture bleue, puis classe le résultat de cette union en fonction du prix. L'exemple suivant affiche la méthode correcte de l'écriture de cette requête pour obtenir le résultat désiré.
SELECT Model, Color, Price
FROM (SELECT TOP (1) Model, Color, Price
FROM dbo.Cars
WHERE Color = 'red'
ORDER BY Price ASC) AS a
UNION ALL
SELECT Model, Color, Price
FROM (SELECT TOP (1) Model, Color, Price
FROM dbo.Cars
WHERE Color = 'blue'
ORDER BY Price ASC) AS b;
GO
En utilisant TOP
et ORDER BY
dans une opération de sous-sélection, vous vérifiez que les résultats de la clause ORDER BY
sont appliqués à la clause TOP
et non au tri du résultat de l’opération de UNION
.
Voici le jeu de résultats.
Model Color Price
------------- ---------- -------
sedan red 10000.00
van blue 8000.00
Limitations
Lorsque vous utilisez TOP
avec INSERT
, UPDATE
, MERGE
ou DELETE
, les lignes référencées ne sont pas organisées dans un ordre quelconque. Vous ne pouvez pas spécifier directement la clause ORDER BY
dans ces instructions. Si vous devez utiliser TOP
pour insérer, supprimer ou modifier des lignes dans un ordre chronologique significatif, utilisez TOP
avec une clause ORDER BY
spécifiée dans une instruction de sous-sélection. Consultez la section Exemples dans cet article.
Vous ne pouvez pas utiliser TOP
dans UPDATE
ou DELETE
instructions sur les vues partitionnée.
Vous ne pouvez pas combiner TOP
avec OFFSET
et FETCH
dans la même expression de requête (dans la même étendue de requête). Pour plus d’informations, consultez clause SELECT - ORDER BY.
Exemples
Les exemples de code Transact-SQL de cet article utilisent l’exemple de base de données AdventureWorks2022
ou AdventureWorksDW2022
, que vous pouvez télécharger à partir de la page d’accueil Microsoft SQL Server Samples and Community Projects.
Category | Éléments syntaxiques proposés |
---|---|
Syntaxe de base | TOP * PERCENT |
Y compris les valeurs de lien | WITH TIES |
Limitation des lignes affectées par DELETE, INSERT ou UPDATE |
DELETE , INSERT , UPDATE |
Syntaxe de base
Les exemples de cette section illustrent les fonctionnalités de base de la clause ORDER BY
à l’aide de la syntaxe minimale requise.
R. Utiliser TOP avec une valeur constante
Les exemples suivants utilisent une valeur constante pour spécifier le nombre d'employés retournés dans le jeu de résultats de la requête. Dans le premier exemple, les 10 premières lignes non définies sont retournées, car une clause ORDER BY
n’est pas utilisée. Dans le deuxième exemple, une clause ORDER BY
est utilisée pour renvoyer les 10 premiers employés récemment embauchés.
USE AdventureWorks2022;
GO
-- Select the first 10 random employees.
SELECT TOP (10) JobTitle, HireDate
FROM HumanResources.Employee;
GO
-- Select the first 10 employees hired most recently.
SELECT TOP (10) JobTitle, HireDate
FROM HumanResources.Employee
ORDER BY HireDate DESC;
GO
B. Utiliser TOP avec une variable
L'exemple suivant utilise une variable pour spécifier le nombre d'employés retournés dans le jeu de résultats de la requête.
USE AdventureWorks2022;
GO
DECLARE @p AS INT = 10;
SELECT TOP (@p) JobTitle, HireDate, VacationHours
FROM HumanResources.Employee
ORDER BY VacationHours DESC;
GO
C. Spécifier un pourcentage
L’exemple suivant utilise PERCENT
pour spécifier le nombre d’employés retournés dans le jeu de résultats de la requête. Il y a 290 employés dans la table HumanResources.Employee
. Comme 5 pour cent de 290 est une valeur fractionnelle, la valeur est arrondie au nombre entier supérieur.
USE AdventureWorks2022;
GO
SELECT TOP (5) PERCENT JobTitle, HireDate
FROM HumanResources.Employee
ORDER BY HireDate DESC;
GO
Inclure des valeurs de liaison
R. Utiliser WITH TIES pour inclure des lignes qui correspondent aux valeurs de la dernière ligne
L’exemple suivant fournit les 10
% des employés ayant le salaire le plus élevé et les retourne dans l’ordre décroissant de leur salaire. En spécifiant WITH TIES
, vous incluez également dans le jeu de résultats les employés dont le salaire est égal au salaire le plus faible retourné (dernière ligne), même s’il dépasse 10
% des employés.
USE AdventureWorks2022;
GO
SELECT TOP (10) PERCENT WITH TIES pp.FirstName,
pp.LastName,
e.JobTitle,
e.Gender,
r.Rate
FROM Person.Person AS pp
INNER JOIN HumanResources.Employee AS e
ON pp.BusinessEntityID = e.BusinessEntityID
INNER JOIN HumanResources.EmployeePayHistory AS r
ON r.BusinessEntityID = e.BusinessEntityID
ORDER BY Rate DESC;
GO
Limiter les lignes affectées par DELETE, INSERT ou UPDATE
R. Utiliser TOP pour limiter le nombre de lignes supprimées
Lorsque vous utilisez une clause TOP (<n>)
avec DELETE
, l’opération de suppression est effectuée sur une sélection non définie de n nombre de lignes. Autrement dit, l’instruction DELETE
choisit n’importe quel nombre de lignes (n) qui répondent aux critères définis dans la clause WHERE
. L’exemple suivant supprime 20
lignes de la table PurchaseOrderDetail
, dont la date d’échéance est antérieure au 1er juillet 2002.
USE AdventureWorks2022;
GO
DELETE TOP (20)
FROM Purchasing.PurchaseOrderDetail
WHERE DueDate < '20020701';
GO
Si vous souhaitez utiliser TOP
pour supprimer des lignes dans un ordre chronologique significatif, utilisez TOP
avec ORDER BY
dans une instruction de sous-sélection. La requête suivante supprime les 10 lignes de la table PurchaseOrderDetail
dont la date d'expiration est la plus proche. Pour garantir que seules 10 lignes sont supprimées, la colonne spécifiée dans l'instruction de sous-sélection (PurchaseOrderID
) constitue la clé primaire de la table. L’utilisation d’une colonne non clé dans l’instruction de sous-sélection peut entraîner la suppression de plus de 10 lignes si la colonne spécifiée contient des valeurs en double.
USE AdventureWorks2022;
GO
DELETE Purchasing.PurchaseOrderDetail
WHERE PurchaseOrderDetailID IN (
SELECT TOP 10 PurchaseOrderDetailID
FROM Purchasing.PurchaseOrderDetail
ORDER BY DueDate ASC
);
GO
B. Utiliser TOP pour limiter le nombre de lignes insérées
L’exemple suivant crée la table EmployeeSales
et insère le nom et les ventes de l’année des 5 premiers employés de la table HumanResources.Employee
. L’instruction INSERT
choisit les cinq lignes retournées par l’instruction SELECT
qui répondent aux critères définis dans la clause WHERE
. La clause OUTPUT
affiche les lignes insérées dans la table EmployeeSales
. La clause ORDER BY
de l’instruction SELECT
n’est pas utilisée pour déterminer les cinq premiers employés.
USE AdventureWorks2022;
GO
IF OBJECT_ID('dbo.EmployeeSales', 'U') IS NOT NULL
DROP TABLE dbo.EmployeeSales;
GO
CREATE TABLE dbo.EmployeeSales
(
EmployeeID NVARCHAR (11) NOT NULL,
LastName NVARCHAR (20) NOT NULL,
FirstName NVARCHAR (20) NOT NULL,
YearlySales MONEY NOT NULL
);
GO
INSERT TOP (5) INTO dbo.EmployeeSales
OUTPUT
inserted.EmployeeID,
inserted.FirstName,
inserted.LastName,
inserted.YearlySales
SELECT sp.BusinessEntityID,
c.LastName,
c.FirstName,
sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.SalesYTD > 250000.00
ORDER BY sp.SalesYTD DESC;
GO
Si vous souhaitez utiliser TOP
pour insérer des lignes dans un ordre chronologique significatif, utilisez TOP
avec ORDER BY
dans une instruction de sous-sélection. L’exemple suivant montre comment procéder. La clause OUTPUT
affiche les lignes insérées dans la table EmployeeSales
. Les cinq premiers employés sont désormais insérés en fonction des résultats de la clause ORDER BY
au lieu de lignes non définies.
INSERT INTO dbo.EmployeeSales
OUTPUT
inserted.EmployeeID,
inserted.FirstName,
inserted.LastName,
inserted.YearlySales
SELECT TOP (5) sp.BusinessEntityID,
c.LastName,
c.FirstName,
sp.SalesYTD
FROM Sales.SalesPerson AS sp
INNER JOIN Person.Person AS c
ON sp.BusinessEntityID = c.BusinessEntityID
WHERE sp.SalesYTD > 250000.00
ORDER BY sp.SalesYTD DESC;
GO
C. Utiliser TOP pour limiter le nombre de lignes mises à jour
L’exemple suivant utilise la clause TOP
pour mettre à jour les lignes d’une table. Lorsque vous utilisez une clause TOP (<n>)
avec UPDATE
, l’opération de mise à jour s’exécute sur un nombre non défini de lignes. Autrement dit, l’instruction UPDATE
choisit n’importe quel nombre de lignes (n) qui répondent aux critères définis dans la clause WHERE
. L'exemple suivant retire 10 clients à un vendeur et les attribue à un autre vendeur.
USE AdventureWorks2022;
UPDATE TOP (10)
Sales.Store
SET SalesPersonID = 276
WHERE SalesPersonID = 275;
GO
Si vous devez utiliser TOP
pour appliquer des mises à jour dans une chronologie significative, vous devez utiliser TOP
avec ORDER BY
dans une instruction de sous-sélection. L'exemple ci-dessous met à jour les heures de congé des 10 employés dont la date d'embauche est la plus ancienne.
UPDATE HumanResources.Employee
SET VacationHours = VacationHours + 8
FROM (SELECT TOP 10 BusinessEntityID
FROM HumanResources.Employee
ORDER BY HireDate ASC) AS th
WHERE HumanResources.Employee.BusinessEntityID = th.BusinessEntityID;
GO
Exemples : Azure Synapse Analytics et Analytics Platform System (PDW)
L’exemple suivant retourne les 31 premières lignes qui correspondent aux critères de la requête. La clause ORDER BY
garantit que les 31 lignes retournées sont les 31 premières lignes en fonction d’un ordre alphabétique de la colonne LastName
.
Utilisation de TOP
sans spécifier de liens.
SELECT TOP (31) FirstName, LastName
FROM DimEmployee
ORDER BY LastName;
Résultat : 31 lignes sont retournées.
À l’aide de TOP
, en spécifiant WITH TIES
.
SELECT TOP (31) WITH TIES FirstName, LastName
FROM DimEmployee
ORDER BY LastName;
Résultat : 33 lignes sont retournées, car trois employés nommés Brown
lien pour la 31e ligne.