在SQL中派生动态列

时间:2017-04-07 05:46:00

标签: sql sql-server

我有一张这样的表:

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(),但无法获得所需的解决方案。所有这三件事都没有用。

任何人都可以向我提出可能的解决方案。

提前致谢。

2 个答案:

答案 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年。

New Restester Sample

+----------+--------+--------------+
| 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。不仅如此,您还需要稍微更改一下查询。但这对你的样本有好处。

Restester Sample

+----------+--------+--------------+
| 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;" ...