2013-05-31 43 views
2

我需要每年返回前10位產品,我如何使用我的以下查詢來執行此操作?每年返回前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 
+1

前10名 - 根據什麼標準? – sgeddes

+0

查看以前的努力類似的任務http://stackoverflow.com/questions/176964/select-top-10-records-for-each-category – xQbert

+0

根據銷售產品的數量 – Etienne

回答

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產品基於FS.OrderQtyTheYear既然你有沒有提到了記錄如何排序的標準刪除。

ROW_NUMBER()排名函數)將產生數目爲每個組中的序列,在這種情況下Year(FS.OrderDate),是基於FS.OrderQty整理出來。記錄將根據生成的序列的值過濾掉。


但是,如果ROW_NUMBER()不會產生對具有相同FS.OrderQty記錄TIE。如果您想要處理它,請使用DENSE_RANK()而不是ROW_NUMBER()

+3

我假設每個「TOP 10」產品年意味着根據'OrderQty * OrderAmount'。 –

+0

可能需要每年爲前10名產品查找ORDER BY FS.OrderQty或FS.OrderAmount。考慮銷售報告。 –

+0

@TimSchmelter好點。不確定,因爲OP沒有提及任何標準。 –

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條款選擇它們。

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; 
+3

他每年都想要十大產品,而不僅僅是一年... –

+0

我已經更改了每年顯示十大產品的代碼。 – Gimmy

+0

,但是它不會將輸出限制爲僅10個值... –