试图找到最受欢迎的产品

时间:2014-12-18 02:11:05

标签: sql sql-server

我正在尝试编写一个查询,根据他们购买的所有产品的数量吸引前五名客户。没问题。但此外,我需要找到这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

2 个答案:

答案 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()来获取您的版本,但这看起来就像您真正想要的那样。