如何从另一列的计数中计算上一行的值

时间:2014-03-07 11:34:54

标签: sql oracle oracle11g

我想创建一个额外的列,用于计算count列中一行的值以及sum列中的前一行。以下是查询。我尝试过使用ROLLUP,但它没有达到目的。

select to_char(register_date,'YYYY-MM') as "registered_in_month"
      ,count(*) as Total_count
from CMSS.USERS_PROFILE a
where a.pcms_db != '*' 
group by (to_char(register_date,'YYYY-MM'))
order by to_char(register_date,'YYYY-MM')

这就是我得到的

registered_in_month   TOTAL_COUNT
-------------------------------------
2005-01                1
2005-02                3
2005-04                8
2005-06                4

但我想要显示的内容如下,包括计为0的月份

registered_in_month   TOTAL_COUNT  SUM
------------------------------------------
2005-01                1           1
2005-02                3           4
2005-03                0           4
2005-04                8           12
2005-05                0           12
2005-06                4           16

1 个答案:

答案 0 :(得分:2)

要在结果中包含缺失的月份,首先需要有完整的月份列表。要做到这一点,你应该找到最早和最近一个月,然后使用heirarchial 查询以生成完整列表。

SQL Fiddle

with x(min_date, max_date) as (
  select min(trunc(register_date,'month')),
         max(trunc(register_date,'month'))
  from users_profile
  )
select add_months(min_date,level-1)
from x
connect by add_months(min_date,level-1) <= max_date;

一旦你有了所有月份,你可以将它加入你的桌子。要获得累积总和,只需使用SUM作为分析函数将计数加起来。

with x(min_date, max_date) as (
  select min(trunc(register_date,'month')),
         max(trunc(register_date,'month'))
  from users_profile
  ),
y(all_months) as (
  select add_months(min_date,level-1)
  from x
  connect by add_months(min_date,level-1) <= max_date
  )
select to_char(a.all_months,'yyyy-mm') registered_in_month,
       count(b.register_date) total_count,
       sum(count(b.register_date)) over (order by a.all_months) "sum"
from y a left outer join users_profile b
         on a.all_months = trunc(b.register_date,'month')
group by a.all_months
order by a.all_months;

输出:

| REGISTERED_IN_MONTH | TOTAL_COUNT | SUM |
|---------------------|-------------|-----|
|             2005-01 |           1 |   1 |
|             2005-02 |           3 |   4 |
|             2005-03 |           0 |   4 |
|             2005-04 |           8 |  12 |
|             2005-05 |           0 |  12 |
|             2005-06 |           4 |  16 |