Ausführen von Multiplikation in T-SQL

8

GTS-Tabelle

%Vor%

Baseline-Tabelle

%Vor%

Erwartetes Ergebnis

%Vor%

SQLFIDDLE

Explantion

Die Baseline-Tabelle hat einen einzelnen Baseline-Wert für jeden CCP.

Der Baseline-Wert sollte auf das erste Quartal jedes CCP angewendet werden und für die nächsten Quartale wird der vorherige Quartals-Summenwert der Basleine sein.

Hier ist eine funktionierende Abfrage in Sql Server 2008

%Vor%

UPDATE:

Um mit mehr als einem Jahr zu arbeiten

%Vor%

Jetzt suche ich nach einer Lösung in Sql Server 2012+ , die SUM OVER(ORDER BY) Funktionalität oder einen besseren Weg nutzt

Versuchte so etwas

%Vor%

Aber nicht Training

    
Pரதீப் 25.09.2015, 17:21
quelle

6 Antworten

6

Die folgende Lösung geht davon aus, dass es immer 3 Zeilen pro Quartal gibt (nur das letzte Quartal könnte teilweise sein), single SELECT, keine Rekursion: -)

%Vor%

Siehe Geige

BEARBEITEN: Logik hinzugefügt, um die Werte & lt; = 0 Geige

zu verarbeiten     
dnoeth 28.09.2015, 16:16
quelle
3

Eine andere Methode, die die Funktionen EXP(SUM(LOG())) trick und only window für die laufende Summe verwendet (keine rekursiven CTEs oder Cursor).

Getestet unter dbfiddle.uk :

%Vor%

So funktioniert es:

  • ( CREATE tables und INSERT übersprungen)

  • 1 , lässt sich nach ccp, year und quart gruppieren und die Summen berechnen:

%Vor% %Vor%
  • 2 verwenden wir den EXP(LOG(SUM()) Trick, um die laufenden Multiplikationen dieser Summen zu berechnen. Wir verwenden BETWEEEN .. AND -1 PRECEDING im Fenster, um die aktuellen Werte zu überspringen, da diese Werte nur für die Basislinien des nächsten Quarts verwendet werden.
    Die Rundung soll Ungenauigkeiten vermeiden, die sich aus der Verwendung von LOG() und EXP() ergeben. Sie können mit ROUND() oder mit NUMERIC :
  • experimentieren

%Vor% %Vor%
  • 3 , wir kombinieren die beiden Abfragen in einem (das ist nicht nötig, es macht die Abfrage nur kompakter, Sie könnten stattdessen zwei CTEs haben) und dann mit gts verbinden, so dass wir jeden Wert multiplizieren können mit der berechneten q2 (was uns die Basis gibt).
    Die CROSS APPLY dient lediglich dazu, die Basisbasislinie für jedes ccp zu erhalten.
    Beachten Sie, dass ich dieses leicht in numeric(22,6) ändere, anstatt auf 2 Dezimalstellen zu runden. Die Ergebnisse sind die gleichen wie beim Beispiel, aber sie können sich unterscheiden, wenn die Zahlen größer oder nicht ganzzahlig sind:

%Vor% %Vor%
    
ypercubeᵀᴹ 24.03.2017 23:13
quelle
2

Ich bin nicht sicher, ob die Frage ist, wie die over() Logik oder führen Sie eine rekursive Cte ​​in 2012 oder berechnen Sie einfach in 2012 ohne rekursive Cte.

Sieht so aus, als hätten Sie versucht, das PRODUCT() aggregation-Äquivalent zu erstellen. Aber wie ich meinen Kommentar einfüge

  

Die Funktion 'Exp' ist keine gültige Fensterfunktion und kann nicht mit der OVER-Klausel verwendet werden.

Also habe ich meine Version ohne rekursive cte für meine Antwort gemacht. Ich füge ein zusätzliches Jahr zu den Beispieldaten mit unterschiedlichen Grundlinien hinzu

  • Berechne den Gesamt gts für jeden Quart
  • Erhalte die Baseline von der ersten Quart
  • Berechne die Basislinie für den anderen Quart , der den Dummy PRODUCT() aggregiert
  • tut

SQL-Geige-Demo

%Vor%

Ausgabe

%Vor%     
Juan Carlos Oropeza 25.09.2015 21:28
quelle
1

Eine weitere Alternative ist die Verwendung von gestapelten / kaskadierten CTEs:

%Vor%     
Felix Pamittan 28.09.2015 02:14
quelle
1

Keine Rekursion, keine Schleifen.

%Vor%     
UnhandledExcepSean 28.09.2015 18:21
quelle
0

Ohne CTE. Ich würde empfehlen, mit den Monaten und Jahren in einem aktuellen Datumsformat zu arbeiten. Ich könnte ein bisschen einfacher werden, den Übergang der Jahre 2015 vs 2016 zu einem einfachen DATEADD (MM, -1, dateCol) zu verwalten, im Gegensatz zu herauszufinden, wann ein Jahr subtrahieren oder hinzufügen. Ich habe diese Lösung nicht implementiert, könnte aber helfen, wenn Sie sie benötigen. Es könnte zu einer ziemlich effektiven Indexierungsstrategie führen, um die Abfrage zu beschleunigen, wenn Sie einen großen Datensatz haben. Ich glaube, es wäre auch möglich, dies mit LAG zu implementieren.

%Vor%     
Brad D 25.09.2015 18:14
quelle