2017-04-07 6 views
0

Ich habe eine Tabelle wie folgt aus:Ableitung Dynamische Spalte in SQL

Store_Id | Week 
---------+-------- 
    A1 | 201601 
    A1 | 201602 
    A1 | 201604 
    A1 | 201606 
    A1 | 201607 
    A2 | 201552 
    A2 | 201603 
    A2 | 201604 
    A2 | 201605 
    A2 | 201608 

Ich brauche eine dynamische Woche Spalte neben diesem abzuleiten, die im Idealfall wird wie folgt aussehen:

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 

Die Logik ist: Die MIN (Woche) für jedes Geschäft gilt als erste Verkaufswoche für das entsprechende Geschäft. Die vorherigen Werte in der dynamischen Woche werden basierend auf der Referenz der ersten Verkaufswoche für jedes Geschäft erhöht.

Ich versuchte Row_Number(), RANK(), DENSE_RANK(), aber konnte nicht eine Lösung erhalten, die benötigt wird. Alle drei Dinge haben nicht funktioniert.

Kann mir jemand mit einer möglichen Lösung vorschlagen.

Vielen Dank im Voraus.

+0

können Sie eine Spalte enthält min haben (Woche) pro insbesondere storeId und sie dann für die dynamische Woche subtrahieren. –

Antwort

1

Edit: Aus der Abfrage dynamisch beliebige Menge zu handhaben von Jahren, nicht nur 1.

New Restester Sample

select d.* 
,((d.week-m.min_w+1) 
    -(48*(cast(left(d.week,4) as int) 
     - cast(left(min_w,4) as int) 
     ) 
    ) 
)as dynamic_week 
from dynw d 
inner join (select store_id,min(week) min_w 
      from dynw 
      group by store_id 
      ) m 
on d.store_id=m.store_id 
order by 1,2 

Ausgabe für komplexere Probe

+----------+--------+--------------+ 
| 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 | 
+----------+--------+--------------+ 

Zurück: Dies ist, was Sie brauchen. Obwohl Ihre Beispieldaten und erwarteten Daten nicht übereinstimmen, ist Diese Lösung eignet sich nur für store_id über 1 Jahr hinweg. Für mehr als das müssen Sie die Abfrage ein wenig ändern. Aber es ist gut für die Probe, die Sie haben.

Restester Sample

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 

Ausgang für meine Probe

+----------+--------+--------------+ 
| 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 | 
+----------+--------+--------------+ 
+0

Hey Utsav, Soll ich wissen, wie bist du zu diesem Faktor 48 gekommen? @Utsav –

+0

Wenn 201602 Woche1 ist, dann ist 201604 '201604-201602 + 1' =' 3'. Wenn nun 201551 Woche 1 ist und 201602 Woche 4, können Sie '201602' nicht einfach von' 201551' subtrahieren und das Ergebnis als '4' erhalten. Als '100 - 52' =' 48' sollten Sie ein Vielfaches von 48 verwenden. Hinweis: Wenn Sie von 2013 bis 2017 zählen möchten, sollten Sie beim Subtrahieren den Faktor '48 * 3' verwenden. – Utsav

+0

Bearbeitete die Antwort, um den Faktor von "48" dynamisch zu machen – Utsav

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 

Ich bin nicht sicher, ob dies auf SQL-Server arbeiten, ich bin nicht auf SQL-Server, den Sie diesen Code comapatible

für SQL-Server machen verwendet