2017-05-30 5 views
0

Suchen Sie nach Hilfe zum Thema "Berechnen von Prozentsätzen aus Werten in einer einzelnen Spalte in einer einzelnen SQL-Tabelle".Jährlichen Prozentsatz aus mehreren Werten aus einer einzelnen Spalte und in einer einzelnen SQL-Tabelle berechnen

Bitte, lassen Sie mich Ihnen ein wenig Heads-up geben (wie unten):

1.) ich in meiner Testumgebung arbeite, die auf SQL2008 ist und Need Code zu implementieren, die auf SQL2012 ist.

2.) ich ein SQL-Cursor verwenden, weil ich die Verarbeitung der Ergebnisse Zeile-für-Zeile benötigen und

3.) Diese Ergebnisse, die ich in eine neue Tabelle bin setze die Abfrage mit:

INSERT INTO tbl_1 (Column_names) 
SELECT @Column_names_from_cursor_variables 

4.) Es gibt (ab sofort) genau 3 Datensätze pro-ID als:

present_year_value (say,MAY2017), 
last_quarter_value (say,MAR2017) 
last_year_value (say,MAY2016) 

wie folgt:

id  yearValue salesQty 
----------------------------- 
1  052017  9876  
1  032017  5432  
1  052016  1000  
---------------------------  
2  052017  9876  
2  032017  5432  
2  052016  1000  
---------------------------  
3  052017  9876  
3  032017  5432  
3  052016  1000  
--------------------------- 

und so weiter ...

Ich brauche die Percentage_YoY (Jahr zu Jahr) sowie Percentage_QoQ (Quarter-On-Viertel) für jeden Block von id wie zu berechnen:

QoQ --> ((present_year_value-last_quarter_value)/last_quarter_value)*100 

YoY --> ((present_year_value-last_year_value)/last_year_value)*100 

Aber irgendwie kann ich den Trick im SQL Cursor nicht bekommen. (Die Verwendung von SQL Cursor ist NICHT obligatorisch, aber ich benötigte eine zeilenweise Berechnung der Ergebnisse, daher bevorzugte ich den Cursor).

+0

Was ist ID hier in dieser Tabelle? (wie Produkt-ID oder eine eindeutige ID in Bezug auf eine andere Tabelle?) –

+0

Hallo Samanvitha, die ID ist Primärschlüssel in der Tabelle und es hat (genau) 3 Datensätze jeweils –

+0

Was ist das Problem? Was ist das Ergebnis, das Sie bekommen, das ist nicht korrekt? – nscheaffer

Antwort

0

Dies ist wahrscheinlich eine längere Antwort als Sie wollen, aber ich möchte einige wichtige Dinge über Ihre Tabelle Setup und warum sie wichtig sind. Meine Erklärung wird ein bisschen zurück sein, aber hoffentlich wird es leicht zu folgen sein.

Das Beispiel Daten, die Sie geben, kann ein wenig verwirrend sein, weil es für jeden ID gleich ist, so werde ich sie ein wenig ändern wie folgt aussehen:

Data 
+ -- + --------- + -------- + 
| Id | YearValue | SalesQty | 
+ -- + --------- + -------- + 
| 1 | 052017 | 9876  | 
| 1 | 032017 | 5432  | 
| 1 | 052016 | 1000  | 
| 2 | 052017 | 6483  | 
| 2 | 032017 | 2211  | 
| 2 | 052016 | 580  | 
| 3 | 052017 | 11316 | 
| 3 | 032017 | 1216  | 
| 3 | 052016 | 9487  | 
+ -- + --------- + -------- + 

zu starten, die Antwort würde sofort klar, wenn Ihre Tabelle wie folgt aussah statt:

Values 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 
| Id | CurrentDate | PresentYearValue | LastQuarterValue | LastYearValue | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 
| 1 | 052017  | 9876    | 5432    | 1000   | 
| 2 | 052017  | 6483    | 2211    | 580   | 
| 3 | 052017  | 11316   | 1216    | 9487   | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 

Dann Ihren Datentyp für das SalesQty Feld unter der Annahme ist nicht eine Dezimalzahl, können Sie die folgende Abfrage verwenden:

select Id 
     , cast((PresentYearValue - LastQuarterValue) as float)/(LastQuarterValue) * 100 as QoQ 
     , cast((PresentYearValue - LastYearValue) as float)/(LastYearValue) * 100 as YoY 
    from Values 

und Sie erhalten die folgenden Ergebnisse:

Results 
+ -- + ------ + ------- + 
| Id | QoQ | YoY  | 
+ -- + ------ + ------- + 
| 1 | 81.81 | 887.6 | 
| 2 | 193.22 | 1017.76 | 
| 3 | 830.59 | 19.28 | 
+ -- + ------ + ------- + 

Sehr einfach und unkompliziert.

ABER ...

Es ist nicht immer möglich sein kann Änderungen wie diese in Ihrer Datenbank zu machen. Zum Beispiel werden die Daten wahrscheinlich für mehr als nur dieses einzelne Problem verwendet und die Speicherung in Ihrem Format ist möglicherweise die beste überhaupt. In diesem Fall wird hier erläutert, wie Sie die Daten so transformieren, dass die gewünschten Ergebnisse erzielt werden.

Um unsere Datentabelle wie unsere Werte Tabelle aussehen zu lassen, benötigen wir eine explizite Bestellung innerhalb der IDs. In diesem Fall können wir das YearValue-Feld aber nur bestellen, wenn es sich um tatsächliche Daten handelt, nicht um Zeichenfolgen. Betrachten Sie die folgende Abfrage:

select *, ROW_NUMBER() over (partition by Id order by YearValue desc) as RN 
    from Values 

Dies gibt uns eine Tabelle ähnlich Daten aber mit einem neuen Feld:

Data 
+ -- + --------- + -------- + -- + 
| Id | YearValue | SalesQty | RN | 
+ -- + --------- + -------- + -- + 
| 1 | 052017 | 9876  | 1 | -- PresentYearValue 
| 1 | 032017 | 5432  | 2 | -- LastQuarterValue 
| 1 | 052016 | 1000  | 3 | -- LastYearValue 
| 2 | 052017 | 6483  | 1 | -- repeat 
| 2 | 032017 | 2211  | 2 | 
| 2 | 052016 | 580  | 3 | 
| 3 | 052017 | 11316 | 1 | 
| 3 | 032017 | 1216  | 2 | 
| 3 | 052016 | 9487  | 3 | 
+ -- + --------- + -------- + -- + 

Beachten Sie die Korrespondenz zwischen RN und (Gegenwart, Last) (Quartal, Jahr) Wert . Wir können diese Korrespondenz ausnutzen, um die Zeilen in Spalten zu "schwenken".

select a.Id 
     , case RN when 1 then a.YearValue end as CurrentDate 
     , case RN when 1 then a.SalesQty end as PresentYearValue 
     , case RN when 2 then a.SalesQty end as LastQuarterValue 
     , case RN when 3 then a.SalesQty end as LastYearValue 
     , a.RN as RN 
    from (
     select *, ROW_NUMBER() over (partition by id order by SalesQty desc) as RN 
      from #Values 
    ) a 

, die uns wie

+ -- + ----------- + ---------------- + ---------------- + ------------- + -- + 
| Id | CurrentDate | PresentYearValue | LastQuarterValue | LastYearValue | RN | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + -- + 
| 1 | 2017-05-01 | 9876    | NULL    | NULL   | 1 | 
| 1 | 2017-05-01 | NULL    | 5432    | NULL   | 2 | 
| 1 | 2017-05-01 | NULL    | NULL    | 1000   | 3 | 
| 2 | 2017-05-01 | 6483    | NULL    | NULL   | 1 | 
| 2 | 2017-05-01 | NULL    | 2211    | NULL   | 2 | 
| 2 | 2017-05-01 | NULL    | NULL    | 580   | 3 | 
| 3 | 2017-05-01 | 11316   | NULL    | NULL   | 1 | 
| 3 | 2017-05-01 | NULL    | 9487    | NULL   | 2 | 
| 3 | 2017-05-01 | NULL    | NULL    | 1216   | 3 | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + -- + 

Mit einer schnellen Gruppierung eine Tabelle gibt wir diese Tabelle kollabieren können.

select a.Id 
     , max(case RN when 1 then a.YearValue end) as CurrentDate 
     , max(case RN when 1 then a.SalesQty end) as PresentYearValue 
     , max(case RN when 2 then a.SalesQty end) as LastQuarterValue 
     , max(case RN when 3 then a.SalesQty end) as LastYearValue 
    from (
     select *, ROW_NUMBER() over (partition by id order by YearValue desc) as RN 
      from Data 
    ) a 
    group by a.Id 

und das gibt uns genau die Werte Tabelle:

Values 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 
| Id | CurrentDate | PresentYearValue | LastQuarterValue | LastYearValue | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 
| 1 | 052017  | 9876    | 5432    | 1000   | 
| 2 | 052017  | 6483    | 2211    | 580   | 
| 3 | 052017  | 11316   | 1216    | 9487   | 
+ -- + ----------- + ---------------- + ---------------- + ------------- + 

Schließlich stecken die letzte Abfrage in einen CTE und es mit der ersten Abfrage kombinieren, um die Werte erhalten Sie wollen:

; with 
    Values as (
     select a.Id 
       , max(case RN when 1 then a.YearValue end) as CurrentDate 
       , max(case RN when 1 then a.SalesQty end) as PresentYearValue 
       , max(case RN when 2 then a.SalesQty end) as LastQuarterValue 
       , max(case RN when 3 then a.SalesQty end) as LastYearValue 
      from (
       select *, ROW_NUMBER() over (partition by id order by YearValue desc) as RN 
        from Data 
      ) a 
      group by a.Id 
    ) 
select Id 
     , cast((PresentYearValue - LastQuarterValue) as float)/(LastQuarterValue) * 100 as QoQ 
     , cast((PresentYearValue - LastYearValue) as float)/(LastYearValue) * 100 as YoY 
    from Values 

Fügen Sie alle zusätzlichen Felder, die Sie wollen, und Ihre in Klausel vor der Klausel from. Hoffe das hilft!

+0

Ohh Gosh @KindaTechy, ich habe diese Tutorial-Art der Antwort gelesen, aber nach dem Aussehen der Dinge, denke ich, dass das funktionieren kann (ich muss das Ganze noch ausprobieren). Bitte geben Sie mir irgendwann Gelegenheit, über diesen Code nachzudenken und probieren Sie ihn mit ein paar kleinen Änderungen aus. Ich werde sicherlich darauf zurückkommen. Nochmals vielen Dank! im Voraus und #allCreditToYou_KindaTechy –

+0

@ E.Hunt Ich hoffe, das funktioniert für Sie. Lass es mich wissen, wenn nicht, und vielleicht können wir herausfinden, warum :) – KindaTechy

+0

Ja, es funktioniert und ich war in der Lage, es mit der Hilfe von Ihrer Logik und ein großes Dankeschön für die Führung zu ändern. Viel gelernt von deiner harten Arbeit. –

Verwandte Themen