【问题标题】:SUM from Specific Date until the end of the month SQL从特定日期到月底 SQL 的 SUM
【发布时间】:2014-10-03 08:17:38
【问题描述】:

我有下表:

ID   GROUPID    oDate       oValue
1    A          2014-06-01  100
2    A          2014-06-02  200
3    A          2014-06-03  300
4    A          2014-06-04  400
5    A          2014-06-05  500
FF. until the end of the month
30   A          2014-06-30  600

我有 3 种 GROUPID,每个组每天会创建一条记录。
我想计算从每个月的第二天到月底的 oValue 的总数。因此,6 月的总和将从 2014 年 6 月 2 日到 2014 年 6 月 30 日。如果是 7 月,则总数将从 2014 年 7 月 2 日到 2014 年 7 月 31 日。

输出将是这样的(示例):

GROUPID   MONTH   YEAR   tot_oValue
A         6       2014   2000
A         7       2014   3000
B         6       2014   1500
B         7       2014   5000

有谁知道如何用 sql 语法解决这个问题?
谢谢。

【问题讨论】:

  • 你能澄清一下你想要的输出吗?似乎回答的人对你真正想要的东西有完全不同的想法。很可能是流动总和还是?

标签: sql sql-server sql-server-2008


【解决方案1】:

您可以使用相关子查询来获得:

SELECT  T.ID,
        T.GroupID,
        t.oDate,
        T.oValue,
        ct.TotalToEndOfMonth
FROM    T
        OUTER APPLY
        (   SELECT  TotalToEndOfMonth = SUM(oValue)
            FROM    T AS T2
            WHERE   T2.GroupID = T.GroupID
            AND     T2.oDate >= T.oDate
            AND     T2.oDate < DATEADD(MONTH, DATEDIFF(MONTH, 0, T.oDate) + 1, 0)
        ) AS ct;

对于您的示例数据,这给出了:

ID  GROUPID ODATE       OVALUE  TOTALTOENDOFMONTH
1   A       2014-06-01  100     2100
2   A       2014-06-02  200     2000
3   A       2014-06-03  300     1800
4   A       2014-06-04  400     1500
5   A       2014-06-05  500     1100
30  A       2014-06-30  600     600

Example on SQL Fiddle

如果您升级后供将来参考,在 SQL Server 2012(及更高版本)中,使用允许排序的窗口聚合函数变得更加容易:

SELECT  T.*,
        TotalToEndOfMonth = SUM(oValue) 
                                OVER (PARTITION BY GroupID, 
                                                    DATEPART(YEAR, oDate), 
                                                    DATEPART(MONTH, oDate) 
                                        ORDER BY oDate DESC)
FROM    T
ORDER BY oDate;

Example on SQL Fiddle

编辑

如果您只希望每个月的 2 日使用此功能,但仍需要所有字段,那么您可以过滤我发布的第一个查询的结果:

SELECT  T.ID,
        T.GroupID,
        t.oDate,
        T.oValue,
        ct.TotalToEndOfMonth
FROM    T
        OUTER APPLY
        (   SELECT  TotalToEndOfMonth = SUM(oValue)
            FROM    T AS T2
            WHERE   T2.GroupID = T.GroupID
            AND     T2.oDate >= T.oDate
            AND     T2.oDate < DATEADD(MONTH, DATEDIFF(MONTH, 0, T.oDate) + 1, 0)
        ) AS ct
WHERE   DATEPART(DAY, T.oDate) = 2;

Example on SQL Fiddle

如果你只关心总数,那么你可以使用:

SELECT  T.GroupID,
        [Month] = DATEPART(MONTH, oDate),
        [Year] = DATEPART(YEAR, oDate),
        tot_oValue = SUM(T.oValue)
FROM    T
WHERE   DATEPART(DAY, T.oDate) >= 2
GROUP BY T.GroupID, DATEPART(MONTH, oDate), DATEPART(YEAR, oDate);

Example on SQL Fiddle

【讨论】:

  • 您好,谢谢您的回答,但结果是错误的。第一次记录应该是2000。因为它只从 6 月 2 日开始计算。干杯,
  • 我建议改进答案,就像我的结果样本一样。然后我会标记你的答案。干杯,
【解决方案2】:

不确定您是否有不同年份的数据

Select YEAR(oDate),MONTH(oDate),SUM(Value) 
From #Temp
Where DAY(oDate)>1
Group By YEAR(oDate),MONTH(oDate)

【讨论】:

  • 是的,我也有不同年份的数据。
  • 那么你需要每年每个月的总和还是只需要按月计算?
  • 每年和每月的总和
  • @Haminteu:好的,我的回答对你有用吗?或者你需要任何修改
  • 您错过了 GroupID 伴侣,但这没关系。谢谢你。干杯,
【解决方案3】:

如果您想按 GROUPID、年份和月份进行分组,应该这样做:

SELECT 
    GROUPID, 
    [MONTH] = MONTH(oDate), 
    [YEAR]  = YEAR(oDate), 
    tot_oValue = SUM(ovalue) 
FROM your_table
WHERE DAY(odate) > 1
GROUP BY GROUPID, YEAR(oDate), MONTH(oDate)
ORDER BY GROUPID, YEAR(oDate), MONTH(oDate)

【讨论】:

    【解决方案4】:

    此查询产生所需的输出:

    SELECT GROUPID, MONTH(oDate) AS "Month", YEAR(oDate) AS "Year", SUM(oValue) AS tot_oValue
      FROM table_name
      WHERE DAY(oDate) > 1
      GROUP BY GROUPID, YEAR(oDate), MONTH(oDate)
      ORDER BY GROUPID, YEAR(oDate), MONTH(oDate)
    

    【讨论】:

      猜你喜欢
      • 2021-01-26
      • 2017-08-28
      • 1970-01-01
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-12
      • 1970-01-01
      相关资源
      最近更新 更多