如何返回每月最订购的商品

时间:2014-07-28 19:54:46

标签: sql sql-server adventureworks

我正在尝试返回2007年每月订购量最大的产品。我希望看到该产品的名称,当月订购的产品数量以及月份。我正在使用AdventureWorks2012数据库。我尝试了几种不同的方法,但每次返回同一个月的多个产品订单,而不是那个月订单数量最多的产品。对不起,如果不清楚。我试图测试自己,所以我自己提出问题并试着回答它们。如果有人知道有这样的问题和答案的网站,那么我可以验证这将是非常有用的!谢谢你的帮助。这是我能够通过查询得到的最远的。

WITH     Ord2007Sum
AS       (SELECT   sum(od.orderqty) AS sorder,
                   od.productid,
                   oh.orderdate,
                   od.SalesOrderID
          FROM     Sales.SalesOrderDetail AS od
                   INNER JOIN
                   sales.SalesOrderHeader AS oh
                   ON od.SalesOrderID = oh.SalesOrderID
          WHERE    year(oh.OrderDate) = 2007
          GROUP BY ProductID, oh.OrderDate, od.SalesOrderID)
SELECT   max(sorder),
         s.productid,
         month(h.orderdate) AS morder --, s.salesorderid
FROM     Ord2007Sum AS s
         INNER JOIN
         sales.SalesOrderheader AS h
         ON s.OrderDate = h.OrderDate
GROUP BY s.ProductID, month(h.orderdate)
ORDER BY morder;

2 个答案:

答案 0 :(得分:0)

制作CTE,按月对产品进行分组并创建总和

;WITH OrderRows AS
(
    SELECT
        od.ProductId, 
        MONTH(oh.OrderDate) SalesMonth,
        SUM(od.orderqty) OVER (PARTITION BY od.ProductId, MONTH(oh.OrderDate) ORDER BY oh.OrderDate) ProdMonthSum
    FROM SalesOrderDetail AS od
    INNER JOIN SalesOrderHeader AS oh
        ON od.SalesOrderID = oh.SalesOrderID
    WHERE year(oh.OrderDate) = 2007
),

制作一个简单的数字表来突破一年中的每个月

Months AS
(
    SELECT 1 AS MonthNum UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 
    UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 
    UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12
)

我们根据数据查询月份表,并根据总和

选择每月的最佳产品
SELECT 
    m.MonthNum,
    d.ProductID,
    d.ProdMonthSum
FROM Months m
OUTER APPLY
(
    SELECT TOP 1 r.ProductID, r.ProdMonthSum 
    FROM OrderRows r
    WHERE r.SalesMonth = m.MonthNum
    ORDER BY ProdMonthSum DESC
) d

答案 1 :(得分:0)

您的分组声明不应包含oh.OrderDate, od.SalesOrderID,因为这会将您的数据汇总到错误的级别。您需要每月最常销售的ProductID,以便按条件成为ProductID, datepart(mm,oh.OrderDate)组。正如Andrew所说,Row_Number函数在这种情况下很有用,因为它允许您创建按月和按钮排序的密钥,并且每个月都会重置。最后,在外部查询中将结果限制为每个月的第一个实例(这是最高数量)。

WITH     Ord2007Sum 
AS(
        SELECT  sum(od.orderqty) AS sorder,
                od.productid,
                datepart(mm,oh.OrderDate) AS 'Month'
                row_number() over (partition by datepart(mm,oh.OrderDate)
                                    Order by datepart(mm,oh.OrderDate)desc, sorder desc) row
        FROM    Sales.SalesOrderDetail AS od
                INNER JOIN
                sales.SalesOrderHeader AS oh
             ON od.SalesOrderID = oh.SalesOrderID
        WHERE    datepart(yyyy,oh.OrderDate) = 2007
        GROUP BY ProductID, datepart(mm,oh.OrderDate)
    )

SELECT  productid,
        sorder,
        [month]
FROM    Ord2007Sum 
WHERE   row =1