【问题标题】:Year to date per month每月年初至今
【发布时间】:2010-02-25 14:50:01
【问题描述】:

我有一张名为 Sales 的表:

ID 日期 部门ID 金额 1 10-12-2009 12 10 2 18-01-2010 3 23 3 08-02-2010 4 7 ...

现在我需要从金额列中检索每个月和每个部门的 YTD 值。

首先我尝试了这个查询:

SELECT MonthSales.[Month], MonthSales.DepartmentID,

    (SELECT SUM(SalesAmount.Amount) FROM Sales AS SalesAmount
        WHERE (SalesAmount.[Date] >= DATEADD(Month, -12, MonthSales.[Month]) 
            AND SalesAmount.[Date] < DATEADD(Month, 1, MonthSales.[Month]))
        AND SalesAmount.DepartmentID = MonthSales.DepartmentID) AS Amount

FROM (SELECT dateadd(month, datediff(month, 0, [Date]),0) AS [Month], DepartmentID
    FROM Sales) AS MonthSales
GROUP BY MonthSales.[Month], MonthSales.DepartmentID

但这会返回内部 SQL Server 错误

为了绕过这个错误,我写了以下查询:

SELECT CompareSales.StartDate, CompareSales.EndDate, CompareSales.DepartmentID,

    (SELECT SUM(SalesAmount.Amount) FROM Sales AS SalesAmount
        WHERE (SalesAmount.[Date] >= CompareSales.StartDate AND SalesAmount.[Date] < 
            DATEADD(Month, 1, CompareSales.EndDate))
        AND SalesAmount.DepartmentID = CompareSales.DepartmentID) AS Amount

FROM (SELECT DATEADD(Month, -12, PeriodSales.EndDate) AS StartDate,    
    PeriodSales.EndDate, PeriodSales.DepartmentID
    FROM (SELECT DISTINCT bms.DATESERIAL(DATEPART(Year, EndSales.[Date]), DATEPART 
        (Month, EndSales.[Date]), 1) AS EndDate, EndSales.DepartmentID
        FROM Sales AS EndSales) AS PeriodSales) AS CompareSales

GROUP BY CompareSales.StartDate, CompareSales.EndDate, CompareSales.DepartmentID
ORDER BY CompareSales.StartDate

此查询返回每个月正确的年初至今金额,但需要 6 分钟来处理所有 4800 条记录。这当然太慢了。谁能帮助我在可接受的时间内(

谢谢,

鲍勃

【问题讨论】:

  • 您是否查看过您的索引,看看是否有可以利用或创建的索引?
  • 您是在寻找年初至今 (YTD) 还是过去 12 个月?
  • 过去 12 个月。我需要记录每年每个月过去 12 个月的总和。因此,例如 2010 年 1 月的一行,总金额从 2009 年 2 月到 2010 年 1 月。

标签: sql sql-server


【解决方案1】:

试试这个:

DECLARE @YourTable table (RowID int, DateOf datetime, DepartmentID int, Amount int)

INSERT INTO @YourTable VALUES (1,'12-10-2009',12,10) --changed dd-mm-yyyy to mm-dd-yyyy so it would work on my system
INSERT INTO @YourTable VALUES (2,'01-18-2010', 3,23)
INSERT INTO @YourTable VALUES (3,'02-08-2010', 4, 7)

SELECT
    DATEPART(mm,DateOf) AS MonthOf,DepartmentID,SUM(Amount) AS TotalAmount
    FROM @YourTable
    WHERE DateOf>='01-01-2010' AND DateOF<'01-01-2011'
    GROUP BY DATEPART(mm,DateOf),DepartmentID

输出

MonthOf     DepartmentID TotalAmount
----------- ------------ -----------
1           3            23
2           4            7

(2 row(s) affected)

如果您仍然需要更快的速度,请创建一个 PERSISTED 计算列:MonthOfDate,即 DATEPART(mm,DateOf) 并在其上添加索引:

ALTER TABLE YourTable ADD MonthOfDate AS DATEPART(mm,DateOf) PERSISTED 

CREATE NONCLUSTERED INDEX IX_YourTable_MonthOfDate 
ON YourTable (MonthOfDate)

甚至:

CREATE NONCLUSTERED INDEX IX_YourTable_MonthOfDate 
ON YourTable (DateOf,MonthOfDate)

如果您不想要 PERSISTED 计算列,请创建索引视图。

【讨论】:

  • 您好 KM,感谢您的回复。不幸的是,您的查询没有返回我需要的结果(每年每个月的最后 12 个月)。注意到我没有在我的帖子中清楚地提到这一点,所以这是我的错。无法创建索引,因为我无法对数据库进行任何更改。
猜你喜欢
  • 2019-06-07
  • 1970-01-01
  • 2018-04-25
  • 2020-01-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多