简体   繁体   English

SQL每月与以前的值之和

[英]SQL sum by month with the previous values

I have following data: 我有以下数据:

  cohort   activity  counter
 -----------------------------
  2010-12    0         470
  2010-12    1          2
  2010-12    2          1
  2010-12    3          1
  2010-12    6          1
  2011-01    0         550
  2011-01    1          1
  2011-01    6          1

I want to sum counter of different activities by month, so the final table looks like: 我想按月对不同活动的计数器求和,所以最终表如下所示:

  cohort   activity  counter   sumResult
 -------------------------------------------
  2010-12     0         470     470
  2010-12     1          2      472
  2010-12     2          1      473
  2010-12     3          1      474
  2010-12     6          1      475
  2011-01     0         550     550
  2011-01     1          1      551
  2011-01     6          1      552

I've tried to do it like this: 我试图这样做:

select
a.activity, a.counter, a.cohort,
(
select sum(b.counter)
from data_table as b
where b.cohort = a.cohort and b.counter >= a.counter
) as sumResult
from data_table as a;
GO;

but it gave me strange results as: 但这给了我奇怪的结果:

 cohort   activity  counter   sumResult
 -------------------------------------------
  2010-12     0         470     470
  2010-12     1          2      472
  2010-12     2          1      475
  2010-12     3          1      475
  2010-12     6          1      475
  2011-01     0         550     550
  2011-01     1          1      552
  2011-01     6          1      552

What could be a problem? 可能是什么问题?

The normal way to do this uses the ANSI standard cumulative sum function: 通常的方法是使用ANSI标准累积和功能:

select dt.*,
       sum(dt.counter) over (partition by dt.cohort order by dt.counter desc)
from data_table dt
order by cohort, counter desc;

If you want to use a subquery, the you need a stable sort, and activity can give you one. 如果要使用子查询,则需要稳定的排序,而activity可以给您一个。 You can use this in the cumulative sum syntax: 您可以在累积和语法中使用它:

select dt.*,
       sum(dt.counter) over (partition by dt.cohort order by dt.counter desc, dt.activity)
from data_table dt
order by cohort, counter desc, activity;

Or using a subquery: 或使用子查询:

select dt.*,
       (select sum(dt2.counter)
        from data_table dt2
        where dt2.cohort = dt.cohort and
              (dt2.counter > dt.counter or
               dt2.counter = dt.counter and dt2.activity < dt.activity)
       )
from data_table dt
order by cohort, counter desc, activity;

Depends on your RDBMS , some(SQL Server,Oracle,Postgresql) of them will accept SUM() OVER() : 取决于您的RDBMS,其中的某些(SQL Server,Oracle,Postgresql)将接受SUM() OVER()

SELECT t.*,
       SUM(t.counter) OVER(PARTITION BY t.cohort ORDER BY t.activity) as sumResult
FROM YourTable t

If it's another, that's a bit more complicated and can be dealt with JOINS 如果是另外一个,那就更复杂了,可以用JOINS处理

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM