2017-06-15 6 views
0

Verwenden von SQL Server 2016. Ich habe die folgenden Beispieldaten:T-SQL-Abfrage - Aggregation

Date  Total_Req. Changed  Deleted  New 
    9/16/2008 271   7   1   3 
    10/14/2008 235   1   10   11 
    10/15/2008 131   2   3   5 
    11/21/2009 190   4   5   2 
    11/22/2009 125   5   12   1 
    11/23/2009 181   6   1   4 
    4/13/2011 300   8   2   8 
    4/26/2011 281   11   7   9 
    4/26/2011 302    5   8   10 

ich leicht pro Monat aggregieren kann, wie etwas mit:

Select cast(Format([Date], 'MM/01/yyyy') as date) as [Date], 
    SUM([Changed]) as [Changed], SUM([Deleted]) as [Deleted], SUM([New]) as 
    [New] GRPUP BY Format([Date], 'MM/01/yyyy') 

So weit so gut , erhalte ich eine Summe von Monat:

Date  Changed Deleted New 
    9/1/2008 7   1 3 
    10/1/2008 3   13 16 
    11/1/2009 15  18 7 
    4/1/2011 19   9 17 

ich brauche aber den Wert von Summe in der Abfrage enthalten _REQ für das letzte Datum in einem Monat, so würde gewünschte Ausgabe sein:

Date Total Req. Changed Deleted New 
    9/1/2008 271  7  1  3 
    10/1/2008 131  3  13 16 
    11/1/2009 181  15 18  7 
    4/1/2011 302  19 9  17 

Wie kann ich das erreichen?

Danke, M. R.

Antwort

2

einfach eine Unterabfrage zurück auf die ursprüngliche Tabelle aus der SELECT-Klausel in den ursprünglichen Tabellen laufen zurück:

bei der
SELECT cast(Format([Date], 'MM/01/yyyy') as date) as [Date], 
    (SELECT TOP 1 [Total_Req.] FROM [MyTable] t0 WHERE Format(t0.[Date], 'MM/01/yyyy') = Format(t.[Date], 'MM/01/yyyy') ORDER BY t0.[Date] DESC) as [Total_Req.], 
    SUM([Changed]) as [Changed], SUM([Deleted]) as [Deleted], SUM([New]) as [New] 
FROM [MyTable] t 
GROUP BY Format([Date], 'MM/01/yyyy') 

oder

SELECT cast(Format([Date], 'MM/01/yyyy') as date) as [Date], 
    MIN(t1.[Total_Req.]) As [Total_Req.], 
    SUM([Changed]) as [Changed], SUM([Deleted]) as [Deleted], SUM([New]) as [New] 
FROM [MyTable] t 
CROSS APPLY (SELECT TOP 1 [Total_Req.] FROM [MyTable] t0 WHERE Format(t0.[Date], 'MM/01/yyyy') = Format(t.[Date], 'MM/01/yyyy') ORDER BY t0.[Date] DESC) t1 
GROUP BY Format([Date], 'MM/01/yyyy') 

Wenn Sie wirklich schnellere Ergebnisse benötigen, werfen Sie einen Blick FORMAT([Date], 'MM/01/yyyy') Ausdruck. Dieser Ausdruck schneidet den Kern dieser Abfrage ab, da er auf drei verschiedene Arten verwendet wird, einschließlich der Übereinstimmungsbedingung für die Unterabfrage oder APPLY. Der Ausdruck ist auch nicht sargeable, was bedeutet, egal welche Indizes Sie haben, werden sie Ihnen nicht mit Abfrageelementen helfen, die diesen Wert benötigen.

Wenn Sie eine berechnete Spalte auf die Tabelle für diesen Ausdruck hinzufügen, können Sie dann die neue Spalte in einem Index verwenden, und Sie sollten viele schnellen Ergebnisse erzielen.

+0

Danke Joel, es funktioniert aber für eine Tabelle mit 55.000 Datensätze ist nicht sehr effizient .... –

+0

55.000 Datensätze ist Erdnüsse. Ich hatte auch eine Version mit CROSS APPLY, aber ich weiß nicht, ob das schneller wäre. –

+0

Ich habe alle Indizes hinzugefügt, aber es dauert ungefähr 3 Minuten, um es auszuführen, komisch ... –

2

einfach eine korrelierte Unterabfrage für die Spalte Gesamt Anf verwenden, die Gesamt Anf Auswahl, wo das Datum der MAX (Datum) für den Monat der Zeile in der äußeren Abfrage ist. (oder verwenden Sie TOP 1 Auftrag nach Datum DESC in der Unterabfrage).