如何获取当月一列的总和?

How to get the sum of a column for the current month?

提问人:User_K47 提问时间:5/16/2023 最后编辑:Dale KUser_K47 更新时间:5/17/2023 访问量:372

问:

我有一个专栏,我想在每年内按月获取它的总和。Amount

我尝试了以下查询,它在一年中效果很好,但月份总结不正确。例如,在这个五月,它总结了不同年份的所有五月。所以我希望它一次对每个当前月份求和。

DECLARE @currentYear int
DECLARE @currentMonth int

SELECT @currentYear = DATEPART(year, GETDATE())
SELECT @currentMonth = DATEPART(month, GETDATE())

SELECT
  SUM(
    CASE
      WHEN DATEPART(month,[Date]) = @currentMonth THEN Amount
      ELSE 0
    END
  ) AS 'This Month',
  SUM(
    CASE
      WHEN DATEPART(year,[Date]) = @currentYear THEN Amount
      ELSE 0
    END
  ) AS 'This Year'
FROM Orders
sql sql-server sql-server-2005

评论

0赞 topsail 5/16/2023
您需要 AND --> WHEN DATEPART(month,[Date]) = @currentMonth AND DATEPART(year,[Date]) = @currentYear
0赞 Stu 5/16/2023
为什么不能简单地使用 [date] > start 和 [date] <= end 进行聚合和过滤,这将比扫描所有行的性能高得多。where
0赞 Dale K 5/16/2023
您是否仍在认真使用 SQL Server 2005?早就该升级了。

答:

1赞 topsail 5/16/2023 #1
SQL 服务器 2012+

这应该会为您提供所需的两个总和,并添加了一个 where 子句,以永远不包含当前年份以外的任何金额:

DECLARE @currentYear INT;
DECLARE @currentMonth INT;

SELECT @currentYear = DATEPART(YEAR, GETDATE());
SELECT @currentMonth = DATEPART(MONTH, GETDATE());

SELECT 
    SUM(CASE WHEN DATEPART(MONTH, [Date]) = @currentMonth THEN Amount ELSE 0 END) AS [This Month],
    SUM(Amount) AS [This Year]
FROM Orders
WHERE 
    [Date] >= DATETIMEFROMPARTS(YEAR(GETDATE()), 1, 1, 0, 0, 0, 0) 
    AND [Date] < DATETIMEFROMPARTS(YEAR(GETDATE()) + 1, 1, 1, 0, 0, 0, 0);
SQL Server 2005/2008

看起来我们还没有 DateTimeFromParts,所以这里有一个替代方法:

DECLARE @currentYear INT;
DECLARE @currentMonth INT;
DECLARE @YearStart DATETIME;
DECLARE @YearEndExclusive DATETIME;

SELECT @currentYear = DATEPART(YEAR, GETDATE());
SELECT @currentMonth = DATEPART(MONTH, GETDATE());

SELECT @YearStart = CAST(CAST(@currentYear AS VARCHAR(4)) + '0101' AS DATETIME);
SELECT @YearEndExclusive = CAST(CAST(@currentYear + 1 AS VARCHAR(4)) + '0101'  AS DATETIME);

SELECT 
    SUM(CASE WHEN DATEPART(MONTH, [Date]) = @currentMonth THEN Amount ELSE 0 END) AS [This Month],
    SUM(Amount) AS [This Year]
FROM Orders
WHERE 
    [Date] >= @YearStart 
    AND [Date] < @YearEndExclusive;

评论

2赞 Thom A 5/16/2023
我很确定是在 2012 年添加的;OP 表明他们正在使用 2005 年(大约 7 年来一直不支持)。DATETIMEFROMPARTS
0赞 Bohemian 5/16/2023 #2

查询将返回所有年份的当月总数。

在子句中添加一个条件 year,然后将 year total 简化为:WHERESUM(Amount()

SELECT
  SUM(CASE WHEN DATEPART(month,[Date]) = @currentMonth THEN Amount END) AS 'This Month',
  SUM(Amount) AS 'This Year'
FROM Orders
WHERE DATEPART(year,[Date]) = @currentYear

另外,请注意,您不需要 ,因为会忽略 null(当没有匹配项时返回)。ELSECASESUM()CASE

0赞 Conor Cunningham MSFT 5/17/2023 #3

这不适用于 SQL Server 2005,但适用于 SQL Server 2022+。您可以使用 DATETRUNC() 将日期截断为不同的时间偏移量(季度、月、日等)。

SELECT SUM(Amount), DATETRUNC(Date, mm) AS date_truncated
FROM ORDERS
GROUP BY DATETRUNC(Date, mm)

DATETRUNC 文档