从 NORTHWIND 数据库中获取每个国家最畅销的产品
Get most sold product for each country from NORTHWIND database
大家好,过去一天我一直在为此苦苦挣扎,我似乎无法弄明白。
我的任务是从名为 NORTHWIND 的流行开源数据库中获取每个国家/地区最畅销的产品:https://northwinddatabase.codeplex.com
我能够到达这个阶段,这是我在 SQL 服务器中的代码:
--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
这给了我以下结果:
很好,但我想找出 MostSoldQuantity 的产品名称。
非常感谢!
P.S 我发表评论 --p.ProductName 我认为它会起作用但它没有,如果有人能解释我为什么 GROUP BY 不自动允许我派生产品名称那行会很棒
首先,从销售产品的数量开始,每个国家/地区,而不仅仅是每个产品。然后对它们进行排名,只选择 RANK = 1 的任何东西。
像...
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
请注意,一个国家/地区可能会供应 相同 数量的不同产品,因此两种产品的等级可能都为 1。查看 ROW_NUMER()
and/or DENSE_RANK()
其他但与 RANK()
类似的行为。
编辑:
要涵盖为什么 SQL 不允许您在最终查询中输入 Product.Name
的一个简单但练习是提出一个问题。
遇到这种情况SQL应该怎么办?
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
MIN
和MAX
的存在使事情变得模棱两可。
你可能很清楚你要执行一个操作by country
并且那个操作是要挑选产品销量最高的那个国家。但它实际上并不明确,对查询的小改动可能会对任何推断的行为产生非常混乱的后果。相反,SQL 的声明性语法对要解决的问题提供了非常清晰/明确/确定的描述。
如果 GROUP BY
子句中未提及表达式,则不能 SELECT
它,而不对其进行聚合。这样一来,就意味着什么或 SQL 引擎应该做什么就没有歧义了。
通过要求您在查询的一个级别规定 get the total sales per country per product
,然后您可以 干净地 在另一级别的查询中声明 and then pick the highest ranked per country
。
这可能会让您感觉最终查询的长度超过 "should" 是必要的。但它也会导致查询完全明确,既可以将查询编译为执行计划,也可以供将来阅读您的代码的其他编码人员使用。
大家好,过去一天我一直在为此苦苦挣扎,我似乎无法弄明白。
我的任务是从名为 NORTHWIND 的流行开源数据库中获取每个国家/地区最畅销的产品:https://northwinddatabase.codeplex.com
我能够到达这个阶段,这是我在 SQL 服务器中的代码:
--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
这给了我以下结果:
很好,但我想找出 MostSoldQuantity 的产品名称。
非常感谢!
P.S 我发表评论 --p.ProductName 我认为它会起作用但它没有,如果有人能解释我为什么 GROUP BY 不自动允许我派生产品名称那行会很棒
首先,从销售产品的数量开始,每个国家/地区,而不仅仅是每个产品。然后对它们进行排名,只选择 RANK = 1 的任何东西。 像...
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
请注意,一个国家/地区可能会供应 相同 数量的不同产品,因此两种产品的等级可能都为 1。查看 ROW_NUMER()
and/or DENSE_RANK()
其他但与 RANK()
类似的行为。
编辑:
要涵盖为什么 SQL 不允许您在最终查询中输入 Product.Name
的一个简单但练习是提出一个问题。
遇到这种情况SQL应该怎么办?
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
MIN
和MAX
的存在使事情变得模棱两可。
你可能很清楚你要执行一个操作by country
并且那个操作是要挑选产品销量最高的那个国家。但它实际上并不明确,对查询的小改动可能会对任何推断的行为产生非常混乱的后果。相反,SQL 的声明性语法对要解决的问题提供了非常清晰/明确/确定的描述。
如果 GROUP BY
子句中未提及表达式,则不能 SELECT
它,而不对其进行聚合。这样一来,就意味着什么或 SQL 引擎应该做什么就没有歧义了。
通过要求您在查询的一个级别规定 get the total sales per country per product
,然后您可以 干净地 在另一级别的查询中声明 and then pick the highest ranked per country
。
这可能会让您感觉最终查询的长度超过 "should" 是必要的。但它也会导致查询完全明确,既可以将查询编译为执行计划,也可以供将来阅读您的代码的其他编码人员使用。