【问题标题】:Calculate sum of budget计算预算总和
【发布时间】:2015-11-02 09:20:31
【问题描述】:

我有这样的餐桌预算:

╔════╦══════╦═══════╦═══════════╦══════╗
║ Id ║ Site ║ Rayon ║   Date    ║ Amt  ║
╠════╬══════╬═══════╬═══════════╬══════╣
║  1 ║   20 ║    23 ║ 2015-11-3 ║  200 ║
║  2 ║   40 ║     2 ║ 2015-12-4 ║   20 ║
║  3 ║   20 ║     3 ║ 2015-11-4 ║  400 ║
║  4 ║   30 ║    13 ║ 2015-11-5 ║  500 ║
║  5 ║   20 ║    23 ║ 2015-08-3 ║  200 ║
╚════╩══════╩═══════╩═══════════╩══════╝

如何计算今天到月底和今天到年底的amt总和?

【问题讨论】:

  • 你有什么尝试吗?查看 Group By 和 Datepart。
  • 你使用的是哪个版本的sql server?
  • @rajeshmpanchal sql server 2008

标签: sql sql-server-2008


【解决方案1】:

遇到这样的问题,你首先要做的是了解如何计算“本月底”和“今年年底”。使用 sql2008,您无法访问有用的函数 EOMONTH(),因此您必须自己计算。

a few different ways of doing this,但我选择了一个,它会在当月最后一天和当年最后一天的午夜前几毫秒计算。

declare @date DATETIME = getdate()

select dateadd(millisecond,-3,DATEADD(MONTH,datediff(MONTH,0,@date)+1,0)) as EOMONTH
select dateadd(millisecond,-3,DATEADD(year,datediff(year,0,@date)+1,0)) as EOYEAR

(注意:-3 是由于 sql server 的 dattime 数据类型具有 minimum accuracy of 3ms 所以从下月初/明年开始花费 3 ms 与您将要的一样准确得到。无论如何,我们要做的只是让日期边界尽可能接近月底/年底)


考虑到这一点已经解决,您可以在 2 个不同的查询中单独使用它们

DECLARE @now DATETIME = GETDATE();
DECLARE @eomonth DATETIME = dateadd(millisecond,-3,DATEADD(MONTH,datediff(MONTH,0,@date)+1,0))
DECLARE @eoyear DATETIME = dateadd(millisecond,-3,DATEADD(year,datediff(year,0,@date)+1,0)) 

SELECT SUM(amt) FROM Budget
WHERE date >= @now AND date <=@eomonth

SELECT SUM(amt) FROM Budget
WHERE date >= @now AND date <= @eoyear

或者,您可以将它们组合起来

SELECT SUM(CASE WHEN DATE<@eomonth THEN Amt ELSE 0 END) AS summonth,
      SUM(CASE WHEN DATE<@eoyear THEN Amt ELSE 0 END) AS sumyear
FROM Budget 
WHERE Date>=@date

【讨论】:

  • 我不喜欢所有毫秒级的操作。你正在做的事情变得不简单了。
  • 什么不简单?从下月初/明年开始取【最小精度-3ms】。它和 SQL2008 一样简单
  • 对于新手来说很难理解为什么是 3 毫秒?为什么不是 5 或 47 毫秒?
  • @GiorgiNakeuri 这是一个有效的观点,我会添加一些解释
  • 所有萨满教都是多余的,因为您可以将包容性检查更改为排他性。这就是我要说的。 date &lt; @eoyear
【解决方案2】:

当月月底:

SELECT SUM(Amt) AS Amt 
FROM TableName
WHERE Date >= CAST(GETDATE() AS DATE) AND 
      Date < DATEADD(m, 1, DATEADD(dd, -DAY(GETDATE()) + 1, CAST(GETDATE() AS DATE)))

对于当年年末:

SELECT SUM(Amt) AS Amt 
FROM TableName
WHERE Date >= CAST(GETDATE() AS DATE) AND 
      Date < CAST(YEAR(GETDATE()) + 1 AS char(4)) + '0101'

【讨论】:

    【解决方案3】:

    很遗憾,您的 sql 版本较旧,无法支持名为 EOMONTH 的系统函数

    这个简单的函数等价于EOMONTH。这个函数通过减少查询长度在复杂的日期计算中非常有用。

    CREATE FUNCTION dbo.endofmonth(@date DATETIME= NULL)
    RETURNS DATETIME
    BEGIN
    RETURN DATEADD(DD, -1, DATEADD(MM, +1, DATEADD(DD, 1 - DATEPART(DD, ISNULL(@date,GETDATE())), ISNULL(@date,GETDATE()))))
    END
    

    要执行的查询:

    SELECT dbo.endofmonth(DEFAULT)  --Current month-end date
    SELECT dbo.endofmonth('02/25/2012') --User-defined month-end date
    

    您的情况

    /**** To get end of current month ****/
    
    SELECT SUM([amt]) FROM budget WHERE [date] >= getdate() AND [date] <= CONVERT(DATE,dbo.endofmonth(DEFAULT))
    
    /**** To get end of current year  ****/
    SELECT SUM([amt]) FROM budget WHERE [date] >= getdate() AND [date] <= CONVERT(DATE,DATEADD(yy, DATEDIFF(yy,0,getdate()) + 1, -1))
    

    【讨论】:

      猜你喜欢
      • 2014-09-16
      • 2012-01-25
      • 1970-01-01
      • 2021-06-25
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      相关资源
      最近更新 更多