我有一张这样的表:
Store_Id | Week
---------+--------
A1 | 201601
A1 | 201602
A1 | 201604
A1 | 201606
A1 | 201607
A2 | 201552
A2 | 201603
A2 | 201604
A2 | 201605
A2 | 201608
我需要在此旁边派生一个动态周列,理想情况下如下:
Store_Id | Week | Dynamic_Week
---------+--------+-------------
A1 | 201602 | 1
A1 | 201603 | 2
A1 | 201605 | 4
A1 | 201606 | 5
A1 | 201607 | 6
A2 | 201552 | 1
A2 | 201603 | 4
A2 | 201604 | 5
A2 | 201605 | 6
A2 | 201608 | 9
逻辑是:每个商店的MIN(周)被视为相应商店的第一周销售。动态周中的先前值将根据每个商店的第一周销售额的参考值递增。
我尝试了Row_Number()
,RANK()
,DENSE_RANK()
,但无法获得所需的解决方案。所有这三件事都没有用。
任何人都可以向我提出可能的解决方案。
提前致谢。
答案 0 :(得分:1)
select a.storeID,a.week,b.min_week,(a.week-b.min_week+1) as Dynamic_week
from
table1 as a
join
(select distinct storeId,min(week) as min_week from table1 group by 1) as b
where a.store_id=b.store_id
我不确定这会对sql-server有效,我不习惯使用sql-server使这段代码与sql-server兼容
答案 1 :(得分:1)
编辑:使查询动态化以处理任何年份,而不仅仅是1年。
+----------+--------+--------------+
| Store_Id | Week | dynamic_week |
+----------+--------+--------------+
| A1 | 201602 | 1 |
| A1 | 201607 | 6 |
| A2 | 201552 | 1 |
| A2 | 201603 | 4 |
| A2 | 201704 | 57 |
| A3 | 201352 | 1 |
| A3 | 201601 | 106 |
+----------+--------+--------------+
更复杂样本的输出
SELECT t1.*,
CASE
WHEN (t1.week-t.week1+1)>=52
THEN (t1.week-t.week1+1)-48
ELSE (t1.week-t.week1+1)
END AS dynamic_week
FROM table1 t1
INNER JOIN
(SELECT store_id,
min(week) AS week1
FROM table1
GROUP BY store_id) t
ON t1.store_id=t.store_id
上一个: 这就是你需要的。虽然您的样本数据和预期数据不匹配, 此解决方案仅适用于跨越1年的store_id。不仅如此,您还需要稍微更改一下查询。但这对你的样本有好处。
+----------+--------+--------------+
| Store_Id | Week | dynamic_week |
+----------+--------+--------------+
| A1 | 201602 | 1 |
| A1 | 201604 | 3 |
| A1 | 201606 | 5 |
| A1 | 201607 | 6 |
| A2 | 201552 | 1 |
| A2 | 201603 | 4 |
| A2 | 201604 | 5 |
| A2 | 201605 | 6 |
| A2 | 201608 | 9 |
+----------+--------+--------------+
我的样本输出
<div class="sprb-b spl-b" style="display: none;" ...