Obtenez le produit le plus vendu pour chaque pays à partir de la database NORTHWIND

Bonjour les gars, je me suis battu avec cela pour le jour passé et je n'arrive juste pas à comprendre.

Ma tâche consiste à dériver le produit le plus vendu pour chaque pays à partir de la database open source populaire appelée NORTHWIND: https://northwinddatabase.codeplex.com

J'ai été en mesure d'arriver à cette étape, voici mon code dans SQL Server:

--Get most sold product for each country WITH TotalProductsSold AS ( SELECT od.ProductID, SUM(od.Quantity) AS TotalSold FROM [Order Details] AS od GROUP BY od.ProductID ) SELECT MAX(TotalProductsSold.TotalSold) AS MostSoldQuantity, s.Country --,p.ProductName FROM Products AS p INNER JOIN TotalProductsSold ON TotalProductsSold.ProductID = p.ProductID INNER JOIN Suppliers AS s ON s.SupplierID = p.SupplierID GROUP BY s.Country ORDER BY MostSoldQuantity DESC 

Cela me donne le résultat suivant:

entrez la description de l'image ici

C'est très bien mais je souhaite find le nom du produit pour MostSoldQuantity.

Merci beaucoup !

Post-scriptum J'ai mis un commentaire –p.ProductName où je pensais que cela fonctionnerait mais il n'a pas et si quelqu'un pouvait m'expliquer pourquoi GROUP BY ne me permet pas automatiquement de dériver le nom du produit pour la ligne qui serait génial

Tout d'abord, commencez par le nombre de produits vendus, par pays, pas seulement par produit. Puis les classr et ne choisir que quelque chose à RANK = 1. Quelque chose comme …

 WITH ProductQuantityByCountry AS ( SELECT s.CountryID, p.ProductID, SUM(od.Quantity) AS Quantity FROM [Order Details] AS od INNER JOIN Products AS p ON p.ProductID = od.ProductID INNER JOIN Suppliers AS s ON s.SupplierID = p.SupplierID GROUP BY s.CountryID, p.ProductID ), RankedProductQuantityByCountry AS ( SELECT RANK() OVER (PARTITION BY CountryID ORDER BY Quantity DESC) AS countryRank, * FROM ProductQuantityByCountry ) SELECT * FROM RankedProductQuantityByCountry WHERE countryRank = 1 

Notez qu'un pays peut fournir une quantité identique de produits différents, donc deux produits peuvent avoir un rang = 1. Regardez ROW_NUMER() et / ou DENSE_RANK() pour d'autres comportements similaires à RANK() .

EDIT: Un simple exercice pour comprendre pourquoi SQL ne vous permet pas de mettre Product.Name dans votre dernière requête est de poser une question.

Que devrait faire SQL dans ce cas?

 SELECT MAX(TotalProductsSold.TotalSold) AS MostSoldQuantity, MIN(TotalProductsSold.TotalSold) AS LeastSoldQuantity, s.Country, p.ProductName FROM blahblahblah GROUP BY s.Country ORDER BY MostSoldQuantity DESC 

La présence d'un MIN et d' un MAX rend les choses ambiguës.

Vous pouvez être clair que vous voulez effectuer une opération by country et que cette opération soit de choisir le produit avec le volume de ventes le plus élevé de ce pays. Mais ce n'est pas vraiment explicite, et de petits changements à la requête pourraient avoir des conséquences très confuses pour tout comportement inféré. Au lieu de cela, la syntaxe déclarative de SQL fournit une description très claire / explicite / déterministe du problème à résoudre.

Si une expression n'est pas mentionnée dans la clause GROUP BY , vous ne pouvez pas la sélectionner, sans l'agréger. C'est ainsi qu'il n'y a aucune ambiguïté quant à ce que l'on entend ou ce que le moteur SQL est censé faire.

En vous demandant de stipuler get the total sales per country per product à un niveau de la requête, vous pouvez ensuite indiquer clairement and then pick the highest ranked per country à un autre niveau de la requête.

Cela peut donner l'printing que vous vous retrouvez avec des requêtes plus longues que «devrait» être nécessaire. Mais il en résulte également des requêtes totalement non ambigues, à la fois pour comstackr la requête dans un plan d'exécution, et pour d'autres codeurs qui liront votre code dans le futur.