2014-10-08 163 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