2016-05-05 6 views
1

Ich habe eine Abfrage in einer Datenbank mit SQL Azure, die eine Reihe von Verkaufszahlen Monat für Monat für eine Reihe von Büros und Mitarbeitern in diesen Büros als zurückgibt im Bild unten: enter image description here die Abfrage, die diese liefert heißt vwOfficeAndNegSalesTotals und sieht wie folgt aus:Jährlich laufende Gesamtspalte basierend auf Werten innerhalb einer Zeile

 
SELECT OfficeID, 
    DATENAME(Month,PipelineDate) + ' ' + DATENAME(Year,PipelineDate) as [PipelineMonth], 
    OfficeName, 
    Negotiator, 
    Status, 
    SUM(Fee) as FeeValue 
FROM vwBankingProjections 
GROUP BY OfficeID, 
    DATENAME(Month,PipelineDate) + ' ' + DATENAME(Year,PipelineDate), 
    OfficeName, 
    Negotiator, 
    Status, 
    DATEPART(Month,PipelineDate), 
    DATEPART(YEAR,PipelineDate) 

ich eine weitere Spalte hinzufügen müssen, die für die Negotiator Lauf insgesamt FeeValue für das Jahr bisher bietet in dieser Zeile, wobei das Jahr "bis Datum" bis einschließlich des Monats dieser Zeile bedeutet. Außerdem sollte es nur den Wert FeeValue ergeben, in dem der Status Zahlung empfangen lautet.

So wäre es so etwas wie dies zurück:

Figures including YTD values

Wie Sie aus der Struktur von vwOfficeAndNegSalesTotals sagen kann, ist die Abfrage, auf dem es basiert (vwBankingProjections) nicht tatsächlichen Daten enthalten, und nicht nur der Text Monat + Jahr - diese Daten befinden sich in der Spalte PipelineDate.

Mein erster Versuch hat mir insgesamt für das Jahr, das eine Zeile für Mai 2016 (zum Zeitpunkt des Schreibens) wäre das Jahr bis heute, aber es muss nur die Summe für das Jahr auf das Datum in erwähnt diese Zeile (also, wenn eine Zeile für April 2016 angezeigt wird, wäre die Summe von Januar - April 2016). Im Fall ist es eine Hilfe, hier ist, was ich mit für das kam:

 
SELECT OfficeID, 
    DATENAME(Year,PipelineDate) as [PipelineYear], 
    OfficeName, 
    Negotiator, 
    SUM(Fee) as YTDFee 
FROM vwBankingProjections 
WHERE Status IN ('Payment Received') 
GROUP BY OfficeID, 
    DATENAME(Year,PipelineDate), 
    OfficeName, 
    Negotiator 

Wenn jemand helfen kann, ich wäre dankbar, da dies ein wenig über meine Skill-Set ist.

Vielen Dank

Andrew

Antwort

1

Sie SUM() OVER() verwenden können.

Tabelle erstellen und auffüllen.

CREATE TABLE dbo.Sales 
(
    OfficeID int NOT NULL, 
    PipelineMonth date NOT NULL 
     CHECK (DAY(PipelineMonth) = 1), 
    OfficeName nvarchar(25) NOT NULL, 
    Negotiator nvarchar(25) NOT NULL, 
    [Status] nvarchar(25) NOT NULL, 
    FeeValue int NOT NULL, 
    FeeValueReceived AS IIF([Status] = N'Payment received', FeeValue, 0) 
); 
GO 

INSERT INTO dbo.Sales (OfficeID, PipelineMonth, OfficeName, Negotiator, [Status], FeeValue) 
    VALUES 
    (1, '2016-01-01', N'London', N'Fred', N'Payment received', 5000), 
    (1, '2016-01-01', N'London', N'Fred', N'Completed', 4800), 
    (1, '2016-01-01', N'London', N'Kate', N'Payment received', 5980), 
    (1, '2016-01-01', N'London', N'Kate', N'Completed', 7000), 
    (1, '2016-01-01', N'London', N'Bob', N'Payment received', 9250), 
    (2, '2016-01-01', N'Birmingham', N'Jo', N'Payment received', 7870), 
    (2, '2016-01-01', N'Birmingham', N'Kathryn', N'Payment received', 3690), 
    (2, '2016-01-01', N'Birmingham', N'Kathryn', N'Completed', 8545), 
    (1, '2016-02-01', N'London', N'Fred', N'Payment received', 6500), 
    (1, '2016-02-01', N'London', N'George', N'Completed', 2575), 
    (1, '2016-02-01', N'London', N'George', N'Payment received', 7500), 
    (1, '2016-02-01', N'London', N'Kate', N'Payment received', 8393), 
    (1, '2016-02-01', N'London', N'Bob', N'Payment received', 6125); 

Dann machen Sie eine SELECT-Anweisung mit SUM() OVER().

SELECT OfficeID, PipelineMonth, OfficeName, Negotiator, [Status], FeeValue, 
     SUM(FeeValueReceived) OVER (PARTITION BY OfficeID, Negotiator, YEAR(PipelineMonth) ORDER BY PipelineMonth, [Status] DESC, FeeValue DESC) AS 'YTD' 
    FROM dbo.Sales 
    ORDER BY PipelineMonth, OfficeID, Negotiator, [Status] DESC, FeeValue DESC 

enter image description here

See Bücher Online> OVER-Klausel (Transact-SQL): https://msdn.microsoft.com/en-us/library/ms189461.aspx

+0

Das ist perfekt - danke. Ich habe den Link zu Online-Büchern gelesen, den Sie gesendet haben, und obwohl es hilfreich ist, finde ich es wirklich schwierig, einige Inhalte zu verstehen. Beispiel: _Wenn ROWS/RANGE angegeben ist und für (kurze Syntax) verwendet wird, wird diese Spezifikation für den Anfangspunkt der Fensterrahmengrenze verwendet und CURRENT ROW wird für die Begrenzungsendung verwendet Punkt. Zum Beispiel ist "ROWS 5 PRECEDING" gleich "ROWS BETWEEN 5 PRECEDING AND CURRENT ROW". _ Ich bin sicher, dass ich nur dicht bin, aber gibt es woanders, wo du empfehlen würdest, könnte ich Hilfe finden? – user1401286

+0

Ja, tut mir leid, Online-Bücher sind nicht immer einfach. Die OVER-Klausel ist auf den ersten Blick ziemlich kompliziert, insbesondere der Teil ROW OR RANGE.Siehe Microsoft SQL Server 2012 T-SQL-Grundlagen von Itzik Ben-Gan> Kapitel 7: Jenseits der Grundlagen der Abfrage> Fensterfunktionen. – RichardCL

+0

Auch er hat ein Follow-up-Buch geschrieben: Microsoft SQL Server 2012 High Performance T-SQL mit Windows-Funktionen (Developer Reference). Ich habe das nicht, aber es ist wahrscheinlich gut. – RichardCL

Verwandte Themen