SQL - 我想选择每周销售额的前5个卷

时间:2014-10-08 12:41:32

标签: sql-server sql-server-2008

我很难找到迄今为止发布的答案。在SQL Server 2008中我尝试每个日历周的前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 |第1项 08/01/2014 | 50 |第4项 01/01/2014 | 40 |第2项 08/01/2014 | 40 |第3项 01/01/2014 | 30 |第3项

我会在镜头下面给出建议

2 个答案:

答案 0 :(得分: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 :(得分: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