如何计算同一组和同月的总数?

时间:2012-03-08 09:49:05

标签: sql

我有一个视图,其格式如下:

channel | theMonth | theCount |
-------------------------------
chaA    |        3 |        5 |
-------------------------------
chaA    |        2 |        2 |
-------------------------------
chaA    |        1 |        4 |
-------------------------------
chaB    |        2 |        1 |
-------------------------------

我想将与当月相同的月份(假设当前月份是3月份)与前一个月相比较,因此3(theMonth)的chaA(频道)将具有该值7(5 + 2)。预期的输出将如下所示:

channel | theMonth | theCount |
-------------------------------
chaA    |        3 |        7 |  --> Note: this row has been updated.
-------------------------------
chaA    |        2 |        2 |  --> Retain the value
-------------------------------
chaA    |        1 |        4 |  --> Retain the value
-------------------------------
chaB    |        2 |        1 |  --> Retain the value
-------------------------------

我一直在使用SQL案例修复此解决方案,如下面的代码,但失败了:

select channel, theMonth, 
case when month(date('2012-03-31')) = theMonth and 
     month(date('2012-03-31')) - 1 = theMonth
         then sum(theCount) 
else sum(theCount) end as theCount
from theView

除了使用SQL案例之外还有其他替代解决方案吗?请不要限制任何数据库技术,因为这是一般的SQL查询。

3 个答案:

答案 0 :(得分:3)

如果您的数据库支持分析函数lag(Oracle,DB2,PostgreSQL,Terradata,?)并且没有缺少月份(即theCount = 0而不是丢失行):

select channel, theMonth,
  case
    when theMonth = 3
    then theCount + lag(theCount) over (partition by channel order by theMonth)
    else theCount
  end as theCount
from theView

答案 1 :(得分:2)

您可以使用UNION

select channel, theMonth, sum(theCount)
from 
(
    (
    select channel, MONTH(TODAY()) as theMonth, sum(theCount)
    from sourceTable
    where theMonth =  MONTH(TODAY()) or theMonth = MONTH(TODAY())-1
    and exists (select theMonth from sourceTable where theMonth=MONTH(TODAY()))
    )
    union
    (
    select channel, theMonth, sum(theCount)
    where theMonth<MONTH(TODAY())
    )
)

这可以工作,它还会检查具有实际月份的行是否存在

答案 2 :(得分:2)

如果我理解正确,则要求报告每个月的计数,当月除外:应该与上个月的计数相加。

在这种情况下我会选择简单的自动加入:

select     curr.month
,          curr.count + coalesce(prev.count, 0)
from       v as curr
left join  v as prev
on         curr.month = month(today())  -- only join if the month is the current month
and        curr.month - 1 = prev.month  -- join with the previous month

我怀疑在具体的例子中,我们还需要考虑频道,因此总查询将成为:

select     curr.channel
,          curr.month
,          curr.count + coalesce(prev.count, 0)
from       v as curr
left join  v as prev
on         curr.month     = month(today())  -- only join if the month is the current month
and        curr.month - 1 = prev.month      -- join with the previous month
and        curr.channel   = prev.channel