APPLY operator

La syntaxe de l’opérateur APPLY est la suivante: requete_1 APPLY requete_2. Elle permet d’exécuter la requete_2 sur chaque ligne issue de la requete_1.

Pour les exemples, j’utilise la base de données AdventureWorks. Les tables SalesOrderHeader et SalesOrderDetail contiennent les commandes et le détail des commandes.

Si je veux afficher les deux produits les moins chers de la commande [SalesOrderID] 43659, j’utilise la requête suivante:

SELECT TOP 2 [ProductID], [UnitPrice] 
    FROM [AdventureWorks2012].[Sales].[SalesOrderDetail] 
WHERE [SalesOrderID] = 43659 ORDER BY [UnitPrice]
Opérateur APPLY

Maintenant, si je veux afficher les deux produits les moins chers pour les commandes dont [TotalDue] est supérieure à 160000, je peux utiliser la requête suivante :

SELECT [SalesOrderID], [ProductID], [UnitPrice]
    FROM [AdventureWorks2012].[Sales].[SalesOrderHeader] S
CROSS APPLY
    (
       SELECT TOP 2 [ProductID], [UnitPrice] 
         FROM [AdventureWorks2012].[Sales].[SalesOrderDetail]
      WHERE [SalesOrderID] = S.SalesOrderID 
        ORDER BY [UnitPrice]
    ) AS O
WHERE TotalDue > 160000
Opérateur APPLY

La requête de gauche me permet de récupérer toutes les commandes ayant TotalDue > 160000 et la requête de droite me donne pour chacune de ces commandes les deux produits les moins chers et leurs prix.

L’opérateur APPLY s’utilise de deux manières CROSS et OUTER. Avec CROSS APPLY, si l’exécution de la requête de droite ne renvoie rien, l’opérateur de gauche ne retourne rien. Avec OUTER APPLY, l’opérateur de droite renvoie des valeurs NULL.

Exemple: je modifie la requête précédente, en remplacement WHERE [SalesOrderID] = S.SalesOrderID  par WHERE [SalesOrderID] = 12. La requête de droite ne renverra rien.

avec CROSS APPLY, on obtient le résultat suivant

SELECT [SalesOrderID], [ProductID], [UnitPrice]   FROM [AdventureWorks2012].[Sales].[SalesOrderHeader] S
CROSS APPLY
(SELECT TOP 2 [ProductID], [UnitPrice] FROM [AdventureWorks2012].[Sales].[SalesOrderDetail]
WHERE [SalesOrderID] = 12 ORDER BY [UnitPrice]) AS O
WHERE TotalDue > 160000
CROSS APPLY

avec OUTER APPLY, on obtient celui-ci.

SELECT [SalesOrderID], [ProductID], [UnitPrice]   FROM [AdventureWorks2012].[Sales].[SalesOrderHeader] S
OUTER APPLY
(SELECT TOP 2 [ProductID], [UnitPrice] FROM [AdventureWorks2012].[Sales].[SalesOrderDetail]
WHERE [SalesOrderID] = 12 ORDER BY [UnitPrice]) AS O
WHERE TotalDue > 160000
OUTER APPLY

Photo by Caspar Camille Rubin on Unsplash

Auteur : Daniel MINKO FASSINOU

Laisser un commentaire




Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.