SQL与前一个值一起按月计算

时间:2017-09-04 11:19:03

标签: sql count sum mysql-5.1

我有以下数据:

  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

我想按月计算不同活动的计数器,所以最终表格如下:

  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

我试图这样做:

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;

但它给了我奇怪的结果:

 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

可能有什么问题?

2 个答案:

答案 0 :(得分:1)

执行此操作的常规方法是使用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;

如果你想使用子查询,你需要一个稳定的排序,而activity可以给你一个。您可以在累积和语法中使用它:

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;

或使用子查询:

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;

答案 1 :(得分:1)

取决于您的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

如果是另一个,那有点复杂,可以处理JOINS