2

我需要每年退回前 10 种产品,我该如何使用以下查询来做到这一点?

SELECT 
   DP.ProductID
   , DP.Name
   , Year(FS.OrderDate) as TheYear
   , FS.OrderQty
   , FS.OrderAmount
FROM dbo.DimProduct AS DP
LEFT JOIN dbo.FactSales as FS on FS.ProductID = DP.ProductID
4

3 回答 3

3

如果您的 RDBMS 支持,这应该很容易Window Functions

SELECT  ProductID,
        Name,
        TheYear,
        OrderQty,
        OrderAmount
FROM    
        (
            SELECT  DP.ProductID
                    ,DP.Name
                    ,Year(FS.OrderDate) as TheYear
                    ,FS.OrderQty
                    ,FS.OrderAmount,
                    ,ROW_NUMBER() OVER() (PARTITION BY Year(FS.OrderDate) 
                                        ORDER BY FS.OrderQty DESC) rn
            FROM    dbo.DimProduct AS DP
                    LEFT JOIN dbo.FactSales as FS 
                        on FS.ProductID = DP.ProductID
        ) s
WHERE   rn <= 10
ORDER   BY TheYear

当前查询将为您10提供每个TheYear基于的产品,FS.OrderQty因为您没有提到如何整理记录的标准。

一个 RANKING 函数)将为每个组生成一个数字序列,在这种情况下ROW_NUMBER(),它是基于 排序的。然后将根据生成的序列的值过滤掉记录。Year(FS.OrderDate)FS.OrderQty


但是,ifROW_NUMBER()不会TIE在具有相同FS.OrderQty. 如果您希望处理它,请使用DENSE_RANK()而不是ROW_NUMBER().

于 2013-05-31T13:14:03.230 回答
3

您想使用该函数row_number()来获得前 10 名。这假设OrderQty定义了前 10 名:

select t.*
from (SELECT DP.ProductID, DP.Name, Year(FS.OrderDate) as TheYear, FS.OrderQty, FS.OrderAmount,
             row_number() over (partition by Year(FS.OrderDate)
                                order by fs.OrderAmount desc
                               ) as seqnum
      FROM dbo.DimProduct DP LEFT JOIN
           dbo.FactSales FS
           on FS.ProductID = DP.ProductID
    ) t
where seqnum <= 10;

该函数row_number()枚举行,从 1 开始。它在每个组内重新开始,如partition by子句所定义(在您的情况下为年份)。数字的顺序基于order by子句(在您的情况下为fs.OrderAmount desc)。因此,每年的十佳产品将有数字 1-10,where条款只是选择它们。

于 2013-05-31T13:15:55.320 回答
0
SELECT 
   DP.ProductID
   , DP.Name
   , Year(FS.OrderDate) as TheYear
   , FS.OrderQty
   , FS.OrderAmount 
   , (FS.OrderQty * FS.OrderAmount) AS FS.Total
FROM dbo.DimProduct AS DP
LEFT JOIN dbo.FactSales as FS on FS.ProductID = DP.ProductID
GROUP BY TheYear, DP.ProductID, FS.Total
ORDER BY FS.Total DESC
WHERE seqnum <= 10;
于 2013-05-31T13:18:33.793 回答