我正在尝试编写一个查询,根据他们购买的所有产品的数量吸引前五名客户。没问题。但此外,我需要找到这5个客户中最受欢迎的产品。
我认为我可以通过查看他们最常购买的产品来做到这一点(所以productID&#39的数量是最大数量),但我不太确定如何获得productID。有任何想法吗?我错了吗?谢谢!
select top 5 c.CustomerID, sum(sod.orderqty) AS 'Amount Purchased',
max(sod.orderqty) AS 'Most Purchased'
from Sales.Customer c
inner join Sales.SalesOrderHeader soh on soh.CustomerID = c.CustomerID
inner join Sales.SalesOrderDetail sod on sod.SalesOrderID = soh.SalesOrderID
inner join Production.Product p on p.ProductID = sod.ProductID
group by c.CustomerID
order by 'Amount Purchased' desc
我尝试了下面的查询,但由于某种原因,包括组中的p.name完全抛出最大值。例如,在此查询中,“最常购买的”商品数量为'应该是20,但它显示为18(这是第二个 - 下一个最大值)
select top 5 soh.CustomerID, sum(sod.orderqty) AS 'Amount Purchased'
, max(sod.orderqty) AS 'Most Purchased', p.name
from Sales.SalesOrderHeader soh
inner join Sales.SalesOrderDetail sod on sod.SalesOrderID = soh.SalesOrderID
inner join Production.Product p on p.ProductID = sod.ProductID
where soh.CustomerID = 29705
group by soh.CustomerID, p.name
order by 'Amount Purchased' desc
答案 0 :(得分:1)
我们可以分两个阶段完成。我使用的是SQL Server 2008。
首先找到前5位客户:
WITH
CTE_TopCustomers
AS
(
select top (5)
c.CustomerID
, sum(sod.orderqty) AS 'Amount Purchased'
from
Sales.Customer c
inner join Sales.SalesOrderHeader soh on soh.CustomerID = c.CustomerID
inner join Sales.SalesOrderDetail sod on sod.SalesOrderID = soh.SalesOrderID
inner join Production.Product p on p.ProductID = sod.ProductID
group by
c.CustomerID
order by 'Amount Purchased' desc
)
然后,为这些客户中的每一位找到最受欢迎的产品。请参阅CROSS APPLY
中的子查询。最受欢迎的"这里指的是客户最多购买的产品。比如说,如果客户在一天内购买了10个单位的某个产品ID=1
,而在第二天购买了20个单位的同一产品ID=1
,则总和将为30.如果同一个客户购买了25个单位另一个产品ID=2
的产品在一天内完成,那么该客户最受欢迎的产品将是ID=1
和30个总产品。
如果您想选择ID=2
作为此示例中最受欢迎的产品,请将SUM
更改为MAX
内的CROSS APPLY
。
SELECT
CTE_TopCustomers.CustomerID
,CTE_TopCustomers.[Amount Purchased]
,CTE_Products.ProductID
,CTE_Products.ProductName
,CTE_Products.SumCustomerProductQty
FROM
CTE_TopCustomers
CROSS APPLY
(
SELECT TOP (1)
p.ProductID
,p.name AS ProductName
,SUM(sod.orderqty) AS SumCustomerProductQty
FROM
Sales.SalesOrderHeader soh on soh.CustomerID = CTE_TopCustomers.CustomerID
inner join Sales.SalesOrderDetail sod on sod.SalesOrderID = soh.SalesOrderID
inner join Production.Product p on p.ProductID = sod.ProductID
GROUP BY
p.ProductID
,p.name
ORDER BY SumCustomerProductQty DESC
) AS CTE_Products
ORDER BY [Amount Purchased] DESC;
对于最终查询,只需将两个代码块放在一起。
答案 1 :(得分:0)
按产品进行中间聚合:
select top 5 CustomerId, sum(AmountPurchased) as AmountPurchased,
max(AmountPurchased) as maxAmountPurchased,
max(case when seqnum = 1 then productId end) as MostPurchased
from (select c.CustomerID, p.ProductId, sum(sod.orderqty) AS AmountPurchased,
row_number() over (partition by c.CustomerId order by sum(sod.orderqty) desc) as seqnum
from Sales.Customer c inner join
Sales.SalesOrderHeader soh
on soh.CustomerID = c.CustomerID inner join
Sales.SalesOrderDetail sod
on sod.SalesOrderID = soh.SalesOrderID inner join
Production.Product p
on p.ProductID = sod.ProductID
group by c.CustomerID, ProductId
) cp
group by CustomerId
order by AmountPurchased desc;
请注意,这与您的查询在最大金额方面略有不同。此版本提供了总产品级别的最大值。您可以在子查询中使用max()
来获取您的版本,但这看起来就像您真正想要的那样。