【问题标题】:SQL - running total when data already groupedSQL - 数据已经分组时的运行总计
【发布时间】:2016-09-05 15:28:07
【问题描述】:

我正在尝试对一些数据进行汇总,并且已经看到了简单的方法。但是,我已经对一些数据进行了分组,这会影响我的代码。我目前有日期和付款类型,以及与之相关的总数。

我现在拥有的是:

create table #testdata
(
mdate date,
pmttype varchar(64),
totalpmtamt int
)

insert into #testdata
select getdate()-7, 'DD', 10
union
select getdate() -7, 'SO', 12
union
select getdate()-6, 'DD', 3
union
select getdate()-5, 'DD', 13
union
select getdate()-5, 'SO', 23
union
select getdate()-5, 'PO', 8

我想要的是:

mdate       |  paymenttype  |  totalpmtamt  |  incrtotal
2016-08-29  |  DD           |  10           |  10
2016-08-29  |  SO           |  12           |  22
2016-08-30  |  DD           |  3            |  25
2016-08-31  |  DD           |  13           |  38
2016-08-31  |  SO           |  8            |  46
2016-08-31  |  PO           |  23           |  69

我已经尝试将我在这里找到的其他代码改编成:

select  t1.mdate, 
        t1.pmttype,
        t1.totalpmtamt, 
        SUM(t2.totalpmtamt) as runningsum
     from #testdata t1
join #testdata t2 on t1.mdate >= t2.mdate and t1.pmttype >= t2.pmttype
group by t1.mdate, t1.pmttype, t1.totalpmtamt
order by t1.mdate

但我得到的只是

mdate       |  paymenttype  |  totalpmtamt  |  incrtotal
2016-08-29  |  DD           |  10           |  10
2016-08-29  |  SO           |  12           |  22
2016-08-30  |  DD           |  3            |  13
2016-08-31  |  DD           |  13           |  26
2016-08-31  |  SO           |  8            |  34
2016-08-31  |  PO           |  23           |  69

有人可以帮忙吗?

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。
  • 您可以在创建示例数据时使用更简单的 VALUES (...)。

标签: sql sql-server-2012 grouping cumulative-sum


【解决方案1】:

进行累积和的ANSI标准方法是:

select t.*, sum(totalpmtamt) over (order by mdate) as runningsum
from #testdata t
order by t.mdate;

并非所有数据库都支持此功能。

如果您的数据库不支持该功能,我会选择相关子查询:

select t.*,
       (select sum(t2.totalpmtamt)
        from #testdata t2
        where t2.mdate <= t.mdate
       ) as runningsum
from #testdata
order by t.mdate;

【讨论】:

  • 谢谢戈登。我将 pmtttype 添加到 over(order by mdate) 中,它按单独的行将其分解,而不仅仅是将日期组合在一起。像魅力一样工作
【解决方案2】:

使用以下查询获得所需的结果(对于 SQL Server)。

with cte_1
     as
     (SELECT *,ROW_NUMBER() OVER(order by mdate  ) RNO
     FROM #testdata)
     SELECT mdate,pmttype,totalpmtamt,(select sum(c2.totalpmtamt)
        from cte_1 c2
        where c2.RNO <= c1.RNO
       ) as incrtotal
     FROM cte_1 c1

输出:

【讨论】:

  • 我赞成您的参赛作品,但您应该按 mdate 排序,而不是选择 1。
  • @cetin 是的。更新
【解决方案3】:

听起来像 SQL Server。

DECLARE @testdata TABLE
    (
      mdate DATE ,
      pmttype VARCHAR(64) ,
      totalpmtamt INT
    );

INSERT  INTO @testdata
        ( mdate, pmttype, totalpmtamt )
VALUES  ( GETDATE() - 7, 'DD', 10 ),
        ( GETDATE() - 7, 'SO', 12 ),
        ( GETDATE() - 6, 'DD', 3 ),
        ( GETDATE() - 5, 'DD', 13 ),
        ( GETDATE() - 5, 'SO', 23 ),
        ( GETDATE() - 5, 'PO', 8 );

SELECT  *,
        SUM(totalpmtamt) OVER ( ORDER BY mdate ROWS UNBOUNDED PRECEDING )
        AS RunningTotal
FROM    @testdata t;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-27
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-20
    • 2021-09-05
    • 2014-04-05
    相关资源
    最近更新 更多