年龄基于行内

时间:2016-05-05 17:41:22

标签: sql sql-server tsql azure-sql-database

我在使用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,其中“到目前为止”表示该行的月份。此外,它应该只收到状态为已收到付款的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

如果有人可以提供帮助,我将不胜感激,因为这有点超出我的技能范围。

非常感谢

安德鲁

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

RichardCL有一个坚实的方法。如果您需要真正的RunningTotal,请参阅https://devjef.wordpress.com/2012/10/20/calculating-running-totals/

中的以下示例