2014-10-08 273 views
1

我正在努力尋找迄今已發佈的解決方案。在SQL Server 2008中,我試着每個日曆周的前5名銷售額。例如,一個數據集其內容SQL - 我想選擇每週銷量前5名的銷售額

01/01/2014 | 50 | Item1 
01/01/2014 | 40 | Item2 
01/01/2014 | 30 | Item3 
01/01/2014 | 20 | Item4 
01/01/2014 | 10 | Item5 
01/01/2014 | 5 | Item6 
01/01/2014 | 2 | Item7 

08/01/2014 | 50 | Item4 
08/01/2014 | 40 | Item3 
08/01/2014 | 30 | Item2 
08/01/2014 | 20 | Item1 
08/01/2014 | 10 | Item5 
08/01/2014 | 5 | Item7 
08/01/2014 | 2 | Item6 

那隻返回

01/01/2014 | 50 | Item1 
01/01/2014 | 40 | Item2 
01/01/2014 | 30 | Item3 
01/01/2014 | 20 | Item4 
01/01/2014 | 10 | Item5 
08/01/2014 | 50 | Item4 
08/01/2014 | 40 | Item3 
08/01/2014 | 30 | Item2 
08/01/2014 | 20 | Item1 
08/01/2014 | 10 | Item5 

目前我的代碼返回前5的所有數據集的,似乎忽略了周因素

任何幫助非常感謝

**在我編輯的道歉我當前的代碼結果得到

01/01/2014 | 50 | Item1
08/01/2014 | 50 | Item4
01/01/2014 | 40 | Item2
08/01/2014 | 40 | Item3
01/01/2014 | 30 |項目3

我給的建議之下的投籃

+2

可能重複的[SQL GROUP BY,前N個項爲每個組(http://stackoverflow.com/questions/15228273/sql-group-by-top-n-items-for-each-組) – DavidG 2014-10-08 12:45:36

+0

但是你的輸出已經返回了前5名每週。你可以分享你的預期結果樣本 – Recursive 2014-10-08 12:46:26

回答

3

您可以使用datepart從日期提取星期,然後用rank獲得前五名每星期。

你沒有提供的列名,所以我要叫他們item_dateitem_scoreitem_name

SELECT item_date, item_score, item_name 
FROM (SELECT *, 
       RANK() OVER (PARTITION BY DATEPART(WEEK, item_date) 
          ORDER BY item_score DESC) AS rk 
     FROM my_table) t 
WHERE rk <= 5 

注: 「前5」 是有點曖昧。無論項目數量多少,我的解決方案都會找到每週排名前五項分數爲的項目。如果您最多隻想購買五件商品,那麼您必須找到另一種訂購方式來處理重複得分的商品(例如,如果有六件商品在一週內獲得最高分數,您會做什麼?)。無論如何,在這種情況下,您應該使用row_number而不是rank

1
declare @tab table 
(
[month] date, 
CustomerCode int, 
ITEM varchar(20) 
) 
insert into @tab 
select 
'01/01/2014',50 ,'Item1' 
union all 
select 
'01/01/2014',40,'Item2' union all 
select 
'01/01/2014',30,'Item3' union all 
select 
'01/01/2014',20,'Item4' union all 
select 
'01/01/2014',10,'Item4' union all 
select 
'08/01/2014',50,'Item1' union all 
select 
'08/01/2014',40,'Item2' union all 
select 
'08/01/2014',30,'Item3' union all 
select 
'08/01/2014',40,'Item4' union all 
select 
'08/01/2014',10,'Item4' 

;with cte as 
(
select DENSE_RANK() OVER(partition by 
datepart(day, datediff(day, 0, [month])/7 * 7)/7 + 1 ORDER BY DatePart(wk, [month])) AS RN,* from @tab 
), 
CTE2 AS 
(
select *,ROW_NUMBER()OVER(PARTITION BY RN ORDER BY (SELECT NULL))R from cte 
) 

Select [month],CustomerCode,ITEM from CTE2 
WHERE R < 4