【问题标题】:Adding all the amounts per month using sql server使用 sql server 每月添加所有金额
【发布时间】:2017-11-02 13:58:16
【问题描述】:

这是我的数据

date           amount
2017-07-10     15.00
2017-07-10     15.00
2017-07-28     25.00
2017-08-01     100.00
2017-08-12     15.00
2017-08-29     200.00
2017-09-18     105.00
2017-09-21     200.00
2017-09-23     25.00
2017-10-12     15.00
2017-10-14     500.00
2017-11-01     200.00
2017-11-02     200.00

我想按月添加,所以我们会得到,在 6 月我总共得到 55,8 月我将得到 315,9 月 330,10 月 515,11 月 400,过去没有金额的日期将是 0 如何我会这样做吗?

这是我的临时表代码:

create table #TempTable
    (month varchar(50),
    amount decimal(18,2))


insert into #TempTable (month)
SELECT TOP 12
DATENAME(MONTH, DATEADD(MONTH,ROW_NUMBER() OVER (ORDER BY object_id) - 1,0))
FROM sys.columns

create table #Data
    (date date,
    amount decimal(18,2))
  insert into #Data(date,amount) values('2017-07-10',15.00)
  insert into #Data(date,amount) values('2017-07-10',15.00)
  insert into #Data(date,amount) values('2017-07-28',25.00)
  insert into #Data(date,amount) values('2017-08-01',100.00)
  insert into #Data(date,amount) values('2017-08-12',15.00)
  insert into #Data(date,amount) values('2017-08-29',200.00)
  insert into #Data(date,amount) values('2017-09-18',105.00)
  insert into #Data(date,amount) values('2017-09-21',200.00)
  insert into #Data(date,amount) values('2017-09-23',25.00)
  insert into #Data(date,amount) values('2017-10-12',15.00)
  insert into #Data(date,amount) values('2017-10-14',500.00)
  insert into #Data(date,amount) values('2017-11-01',200.00)
  insert into #Data(date,amount) values('2017-11-02',200.00)

  select * from #Data
  select * from #TempTable
drop table #TempTable
drop table #Data

PS。只需更新#TempTable 并将总数放在上面,谢谢:)

【问题讨论】:

  • 提示:GROUP BYMONTH().
  • 加上一个测试数据,还请包括预期结果作为文本和任何查询尝试
  • SQL Server Group By Month的可能重复
  • 请记住,如果按月分组,如果日期范围超过 12 个月,则可能需要按年分组。

标签: sql sql-server


【解决方案1】:

从数据表更新临时表

update #TempTable
set amount = d.amount from ( select  datename(month, date) date
                                     , SUM(amount) amount from #Data
                                     group by datename(month, date)
                                     ) d inner join #TempTable t on t.month = d.date

                                     select * from #TempTable

【讨论】:

    【解决方案2】:

    您的要求之一是:

    没有金额的过去日期将为 0

    您的数据集不包含此内容,因此我在下面的示例代码中添加了另外两行。我还添加了不同的年份来说明不同年份会发生什么。我将 #data 中的所有值与 CTE 联合起来,该 CTE 选择年份、每年的每个月 # 年和 0。当求和时,大多数 0 条目被消除,但一年中没有 #Data 值的月份仍然是数量= 0。对该结果进行子查询以消除 #data 中最小和最大日期范围之外的 0 行。

    create table #Data (date date, amount decimal(18,2))
    insert into #Data(date,amount) values('2017-07-10',15.00)
    insert into #Data(date,amount) values('2017-07-10',15.00)
    insert into #Data(date,amount) values('2017-07-28',25.00)
    insert into #Data(date,amount) values('2017-08-01',100.00)
    insert into #Data(date,amount) values('2017-08-12',15.00)
    insert into #Data(date,amount) values('2017-08-29',200.00)
    insert into #Data(date,amount) values('2017-09-18',105.00)
    insert into #Data(date,amount) values('2017-09-21',200.00)
    insert into #Data(date,amount) values('2017-09-23',25.00)
    insert into #Data(date,amount) values('2017-10-12',15.00)
    insert into #Data(date,amount) values('2017-10-14',500.00)
    insert into #Data(date,amount) values('2017-11-01',200.00)
    insert into #Data(date,amount) values('2017-11-02',200.00)
    
    --additional test values
    insert into #Data(date,amount) values('2017-05-04',5.00)
    insert into #Data(date,amount) values('2018-02-22',1.00)
    
    DECLARE @minYear int =  (SELECT YEAR(MIN(date)) FROM #data)
           ,@minMonth int =  (SELECT MONTH(MIN(date)) FROM #data)
           ,@maxYear int =  (SELECT MAX(YEAR(date)) FROM #data)
           ,@maxMonth int =  (SELECT MONTH(MAX(date)) FROM #data);
    
    WITH cteYear AS 
    (
      SELECT @minYear AS num
      UNION ALL
      SELECT num + 1 FROM cteYear WHERE num + 1 <= @maxYear
    )
    
    SELECT dT.dateyear
          ,DateName( month , DateAdd( month , dT.datemonth, -1 ) ) AS [month]
          ,SUM(dT.amount) AS [Sum Amount]
      FROM (
             SELECT YEAR(date) AS [dateyear], MONTH(date) AS [datemonth], amount -- AS [SumAmount]     
               FROM #Data D       
    
             UNION ALL
    
             SELECT num, monthlist.month, 0 
               FROM cteYear CROSS JOIN (SELECT 1 AS [month] UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4  UNION ALL 
                                        SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL 
                                        SELECT 9 UNION ALL SELECT 10 UNION ALL SELECT 11 UNION ALL SELECT 12
                                       ) AS monthlist
           ) AS dT
    WHERE (@minYear <> @maxYear AND dateyear = @minYear AND datemonth >= @minMonth)
          OR
          (@minYear <> @maxYear AND dateyear = @maxYear AND datemonth <= @maxMonth)
          OR
          (@minYear <> @maxYear AND dateyear <> @minYear AND dateyear <> @maxYear)
          OR
          (@minYear = @maxYear AND datemonth >= @minMonth AND datemonth <= @maxMonth)
    
    
    GROUP BY dateyear, datemonth
    ORDER BY dateyear, datemonth
    

    给出输出:

    dateyear    month      Sum Amount
    2017        May        5.00
    2017        June       0.00
    2017        July       55.00
    2017        August     315.00
    2017        September  330.00
    2017        October    515.00
    2017        November   400.00
    2017        December   0.00
    2018        January    0.00
    2018        February   1.00
    

    【讨论】:

      【解决方案3】:

      使用下面的代码:

      SELECT Res1.[Month]
               ,ISNULL(Res2.Amount,0)
        FROM #TempTable Res1
        LEFT JOIN
        (
        select DATENAME(MONTH,Res1.date) AS [Month]
               ,SUM(amount) AS Amount 
        from #Data Res1
        GROUP BY DATENAME(MONTH,Res1.date) 
        )Res2 ON Res2.[Month] = Res1.[Month]
      

      【讨论】:

      • 请了解如何格式化您的代码。此外,这个答案与另一个答案有相同的问题。
      【解决方案4】:
        SELECT a.Month,SUM(ISNULL(b.Amount,0)) 
        FROM  #TempTable a
        LEFT JOIN #Data b
        ON a.Month = DATENAME(MONTH,date)
        GROUP BY a.Month
      

      更新

         UPDATE a
        SET Amount = ISNULL(GroupSuma,0)
        FROM  #TempTable a
        LEFT JOIN
        (
            select DATENAME(MONTH,date) as month, SUM(b.Amount) as GroupSuma
            FROM #Data b
            GROUP BY DATENAME(MONTH,date)
        ) as c
        ON a.Month = c.Month
      

      【讨论】:

      • 如果日期范围超过 1 年,这将失败。
      • 你明白了,但事情是月份,不是按顺序排列的,而是从四月开始而不是一月
      • @GGw 请不要(加一)。
      • @GGw 如果它没有回答你的问题,它怎么可能是正确的查询?
      猜你喜欢
      • 2017-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多