2017-08-04 3 views
0

Tabellenformat ist wie folgt:berechnen stdev über einen variablen Bereich in SQL Server

Date  ID subID value 
----------------------------- 
7/1/1996 100 1  .0543 
7/1/1996 100 2  .0023 
7/1/1996 200 1 -.0410 
8/1/1996 100 1 -.0230 
8/1/1996 200 1  .0121 

Ich möchte STDEV auf den Wert Spalte anzuwenden, wenn Datum innerhalb eines bestimmten Bereichs liegt, auf der ID-Spalte zu gruppieren.

gewünschte Ausgabe würde wie folgt erhalten:

DateRange, ID, std_v 
1 100 .0232 
2 100 .0323 
1 200 .0423 

Eine Idee, die ich je hatte, das funktioniert aber ist klobig, beinhaltet eine zusätzliche Spalte zu schaffen zu identifizieren, a '(die ich ‚Partition‘ genannt habe) Gruppe von Werten, über die STDEV genommen wird (mithilfe der OVER-Funktion und PARTITION BY, die auf die Variablen "partition" und "ID" angewendet werden).

Erstellen der Partitionsgröße einen CASE-Anweisung vor handelt, bei denen ein bestimmter Datensatz eine Partition auf der Grundlage seiner Datum

... 
, partition = CASE 
       WHEN date BETWEEN '7/1/1996' AND '10/1/1996' THEN 1 
       WHEN date BETWEEN '10/1/1996' AND '1/1/1997' THEN 2 
... 

Im Idealfall innerhalb eines bestimmten Bereichs (dh fallen zugeordnet ist, würde ich in der Lage sein STDEV bewerben und die OVER-Funktion Partitionierung auf der Variablen-ID und variable Datumsbereiche (zB sagen, 3 Monate für ein bestimmtes Referenzdatum). Sobald dies für den oben beschriebenen 3-Monats-Zeitraum funktioniert, würde ich gerne in der Lage sein, das Datum zu machen Bereichsvariable, die zu Beginn des Programms eine zusätzliche Variable '@dateRange' erstellt, um diese für 2, 3, 6, usw. Monatsbereiche ausführen zu können

+0

IMO Sie sind auf dem richtigen Weg, was zu tun ist. Wo genau stecken Sie fest? – Alex

+0

Warum nicht einfach 'where' mit Startdatum und Enddatum verwenden? –

+0

@Alex, nicht stecken, per se, nur manuell erstellen Partitionen für Dutzende von Intervallen scheint ineffizient, und ich würde eine elegantere Lösung bevorzugen – Chris

Antwort

0

Ich habe eine Lösung für meine Frage gefunden.

Sie können die ursprüngliche Tabelle mit einer zweiten Tabelle verknüpfen, die aus einer eindeutigen Liste der Daten in der ersten Tabelle besteht und eine BETWEEN-Klausel anwendet, um den gewünschten Bereich anzugeben.

Beispielabfrage unten.

Initial Tabelle mit Spalten (#excessRets): Datum, ID, SubID, Wert

zweite Tabelle eine eindeutige Liste der Daten in der vorherigen, mit Säulen (#dates): Datum

select d.date, er.id, STDEV(er.value) 
from #dates d 
inner join #excessRet er 
on er.date between DATEADD(m, -36, d.date) and d.date 
group by d.date, er.id 
order by er.id, d.date 

Um den oben genannten gewünschten nächsten Schritt zu erreichen (Bereichsvariable erstellen), erstellen Sie einfach eine Variable am Anfang und ersetzen "36" durch die Variable.