2017-02-03 3 views
1

Wir möchten einen Datensatz erstellen, der die monatliche durchschnittliche Anzahl in unserer Gerätetabelle nach Status sortiert anzeigt: Aktiv, Verschrottet, Neu.Berechnen eines laufenden Monatsdurchschnitts in SQL Server

Je mehr ich darüber nachdenke, scheint es, dass die einzige Möglichkeit, dies zu erreichen, zuerst eine Container-Tempentabelle erstellt und jeden Datensatz mit einem Cursor auswertet.

kann dies ohne eine temporäre Tabelle erreicht werden?

Das folgende zeigt nur die Felder, wir arbeiten mit:

SELECT a1.statusdate, a1.CreateDate, 
RunningTotalActive = count([status]='Active'), 
RunningTotalScrapped = count([status]='Scrapped'), 
NewEquipment = count(Month(a1.CreateDate)) 
FROM dbo.Equipment AS a1 
INNER JOIN dbo.Equipment AS a2 
ON a2.statusdate <= a1.CreateDate 
GROUP BY a1.statusdate 
ORDER BY a1.statusdate desc 
+2

Beispieldaten und erwartete Ergebnisse würde mit dieser Art von Frage helfen. – pmbAustin

+0

Welche Version von SQL Server? –

+0

@John MS SS 2012 - danke – jonno

Antwort

0

Ich bin ein paar Girlanden über Ihre Daten zu machen, aber die Idee ist es, die Summen über einfache Zählungen von Monat zu mitteln; CTEs verwenden.

; WITH A AS (
    SELECT a1.statusdate, 
    Active = CASE a1.[status] WHEN 'Active' THEN 1 ELSE 0 END, 
    Scrapped = CASE a1.[status] WHEN 'Scrapped' THEN 1 ELSE 0 END, 
    New = CASE WHEN a2.statusdate = a1.CreateDate THEN 1 ELSE 0 END --Guessing here that "new" means status date and create date are the same 
    FROM dbo.Equipment AS a1 
    INNER JOIN dbo.Equipment AS a2 
    ON a2.statusdate <= a1.CreateDate --"status" can be older than "create" for a piece of equipment? Not sure I understand this criteria. May need sample data. 
), B AS (
    SELECT Y = DATEPART(YEAR, statusdate) 
    , M = DATEPART(MONTH, statusdate) 
    , SumActive = SUM(Active) 
    , SumScrapped = SUM(Scrapped) 
    , SumNew = SUM(New) 
    FROM A 
    GROUP BY DATEPART(YEAR, statusdate), DATEPART(MONTH, statusdate) 
) 
SELECT Y, M, 
    RunningTotalActive = AVG(SumActive)OVER(PARTITION BY Y,M ORDER BY Y,M), 
    RunningTotalScrapped = AVG(SumScrapped)OVER(PARTITION BY Y,M ORDER BY Y,M), 
    NewEquipment = AVG(SumNew)OVER(PARTITION BY Y,M ORDER BY Y,M) 
FROM B; 
0

Können Sie einige Beispieldaten anzeigen? Ich hatte Ihr Skript nach meinem Verständnis geändert. Kannst du es versuchen?

SELECT YEAR(a1.statusdate) AS yr,MONTH(a1.statusdate) AS mon, 
      RunningTotalActive = count(CASE WHEN a1.[status]='Active' THEN 1 ELSE NULL END), -- or SUM(CASE WHEN [status]='Active' THEN 1 ELSE 0 END), 
      RunningTotalScrapped = count(CASE WHEN a1.[status]='Scrapped' THEN 1 ELSE NULL END), 
      NewEquipment = count(CASE WHEN YEAR(a1.CreateDate)*12+ MONTH(a1.CreateDate)= YEAR(a1.statusdate)*12+ MONTH(a1.statusdate)) THEN 1 ELSE NULL END) 
    FROM dbo.Equipment AS a1 
    GROUP BY YEAR(a1.statusdate),MONTH(a1.statusdate) 
    ORDER BY YEAR(a1.statusdate),MONTH(a1.statusdate) DESC 
Verwandte Themen