我有一个视图,其格式如下:
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查询。
答案 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