
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:
123 SELECT
TOP
2 [ProductID], [UnitPrice]
FROM
[AdventureWorks2012].[Sales].[SalesOrderDetail]
WHERE
[SalesOrderID] = 43659
ORDER
BY
[UnitPrice]

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 :
12345678910 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

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
12345 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

avec OUTER APPLY, on obtient celui-ci.
12345 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

Photo by Caspar Camille Rubin on Unsplash
Laisser un commentaire