2016-05-05 34 views
1

我在使用SQL Azure的數據庫中查詢,它爲這些辦公室內的一組辦公室和員工逐月返回一組銷售數字, enter image description here 返回這就是所謂的vwOfficeAndNegSalesTotals,看起來像這樣的查詢:年迄今爲止運行的總列數基於連續的值

 
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) 

我需要添加另一列,它提供了一個運行總計FeeValue爲今年迄今爲止的談判下面的圖片在那一行中,「到目前爲止」的年份意味着直到幷包括該行的月份。此外,它應該只收取狀態爲收到付款的費用值。

因此,它將返回是這樣的:

Figures including YTD values

你可以從vwOfficeAndNegSalesTotals的結構來講,在查詢時,它是基於(vwBankingProjections)不包括實際日期,而不是僅僅文本Month + Year - 這些日期位於PipelineDate列中。

我的第一次嘗試讓我在2016年5月(在撰寫本文時)連續觀看一年的總數是今年迄今爲止的一年,但它只需顯示本年度到本文提到的日期那一排(所以如果連續觀看2016年4月,將會是2016年1月至4月的總數)。在情況下,它的任何幫助,這就是我想出了是:

 
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 

如果有人可以幫助,我會很感激,因爲這是一個有點超出我的技能設置。

非常感謝

安德魯

回答

1

你可以用SUM()OVER()。

創建並填充表格。

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); 

然後用SUM()OVER()做一個SELECT語句。

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

請參閱聯機叢書> OVER子句(Transact-SQL):https://msdn.microsoft.com/en-us/library/ms189461.aspx

+0

這很完美 - 謝謝。我已閱讀您發送的聯機叢書鏈接,雖然它確實有幫助,但我發現很難理解其中的一些內容。例如: 如果指定了ROWS/RANGE,並且<窗口框架在前>用於<窗口框架範圍>(短語法),則此規範用於窗口框架邊界起點,並且CURRENT ROW用於邊界終點點。例如「ROWS 5 PRECEDING」等於「ROWS between 5 PRECEDING AND CURRENT ROW」。 _ 我確信我只是很密集,但有其他地方你會推薦我可能會找到幫助嗎? – user1401286

+0

是的,抱歉,聯機叢書並不總是那麼容易。 OVER子句乍看起來相當複雜,特別是ROW OR RANGE部分。請參閱Itzik Ben-Gan的「Microsoft SQL Server 2012 T-SQL基礎知識>第7章:超越查詢基礎>窗口函數」。 – RichardCL

+0

他還編寫了一本後續書籍:使用Windows函數的Microsoft SQL Server 2012高性能T-SQL(開發人員參考)。我沒有那個,但它可能是好的。 – RichardCL