我有一个样本表:
Month Id1 Id2 Id3 value1 value2
Dec-17 1 1 1 10 10
Jan-18 1 1 1 null null
Feb-18 1 1 1 20 10
Mar-18 1 1 1 20 10
Apr-18 1 1 1 10 30
Jan-18 2 2 2 10 20
Mar-18 2 2 2 10 10
我的表的复合键是月+ Id1 + Id2 + Id3。 根据季度的月份,我想应用一些逻辑。 例如,对于本季度的每个月,产出应为前几个月的总和以及当前和未来月份的总和
我想使用滞后和导联功能,我使用分区(Id1,Id2,Id3),所以我不想要null我想要Id1,Id2,Id3中的0。我认为使用左外join以获取所有月份,但会在Id1,Id2,Id3中填充null或0。
我想根据月份使用滞后和潜在客户,我需要考虑逻辑中的下一个和前几个月 有人可以帮忙吗
答案 0 :(得分:4)
您似乎想要显示该月所在季度的总值。您可以使用分析sum()
而不是lag()
:
sum(value) over (partition by id1, id2, id3, trunc(month, 'Q'))
演示,通过CTE获取样本数据,还包括有趣的季度至今的价值::
with your_table(Month, Id1, Id2, Id3, value) as (
select date '2017-12-01', 1, 1, 1, 10 from dual
union all select date '2018-02-01', 1, 1, 1, 10 from dual
union all select date '2018-04-01', 1, 1, 1, 10 from dual
union all select date '2018-05-01', 1, 1, 1, 10 from dual
union all select date '2018-09-01', 1, 1, 1, 20 from dual
)
select to_char(month, 'Mon-RR', 'nls_date_language=english') as month,
id1, id2, id3, value,
sum(value) over (partition by id1, id2, id3, trunc(month, 'Q')) as qtr,
sum(value) over (partition by id1, id2, id3, trunc(month, 'Q')
order by month) as qtd
from your_table;
MONTH ID1 ID2 ID3 VALUE QTR QTD
------ ---------- ---------- ---------- ---------- ---------- ----------
Dec-17 1 1 1 10 10 10
Feb-18 1 1 1 10 10 10
Apr-18 1 1 1 10 20 10
May-18 1 1 1 10 20 20
Sep-18 1 1 1 20 20 20
缺少月份不存在因此不影响总和。 (如果有几个月但是将值设置为null而不是零,那么你会遇到问题;但是那时你可以合并它们。)
根据您的最新更新,您有两个值;您希望在本季度的任何前几个月使用value1
,并在本季度和本季度的任何未来月份使用value2
。
你可以得到那些有合适窗口条款的人;再次使用CTE为您提供新的样本数据:
with your_table(month, id1, id2, id3, value1, value2) as (
select date '2017-12-01', 1, 1, 1, 10, 10 from dual
union all select date '2018-01-01', 1, 1, 1, null, null from dual
union all select date '2018-02-01', 1, 1, 1, 10, 10 from dual
union all select date '2018-03-01', 1, 1, 1, 20, 10 from dual
union all select date '2018-04-01', 1, 1, 1, 10, 30 from dual
union all select date '2018-05-01', 1, 1, 1, 10, 10 from dual
union all select date '2018-09-01', 1, 1, 1, 20, 10 from dual
)
select to_char(month, 'Mon-RR', 'nls_date_language=english') as month,
id1, id2, id3, value1, value2,
coalesce(sum(coalesce(value1, 0)) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between unbounded preceding and 1 preceding
), 0) as qbd_value1,
coalesce(sum(coalesce(value2, 0)) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between current row and unbounded following
), 0) as qfd_value2,
coalesce(sum(coalesce(value1, 0)) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between unbounded preceding and 1 preceding
), 0)
+
coalesce(sum(coalesce(value2, 0)) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between current row and unbounded following
), 0) as qtr_value
from your_table;
得到:
MONTH ID1 ID2 ID3 VALUE1 VALUE2 QBD_VALUE1 QFD_VALUE2 QTR_VALUE
------ --- --- --- ------ ------ ---------- ---------- ----------
Dec-17 1 1 1 10 10 0 10 10
Jan-18 1 1 1 0 20 20
Feb-18 1 1 1 10 10 0 20 20
Mar-18 1 1 1 20 10 10 10 20
Apr-18 1 1 1 10 30 0 40 40
May-18 1 1 1 10 10 10 10 20
Sep-18 1 1 1 20 10 0 10 10
您无需选择value1
(qbd_value1
)之前的季度总和或value2
之间的季度总和(qfd_value2
)价值分开,我只是包括它们,所以你可以看到/检查它们;相关部分是将它们加在一起生成qtr_value
。
所以:
对于Jan,它给出了Jan value2(null-> 0)+ Feb value2(10)+ Mar value2(10)=> 20。
对于2月,它给出了Jan value1(null-> 0)+ Feb value2(10)+ Mar value2(10)=> 20。
对于Mar,它给出了Jan value1(null-> 0)+ Feb value1(10)+ Mar value1(10)=> 20。
不是最有帮助的样本数据......
使用您的最新样本数据:
with your_table(month, id1, id2, id3, value1, value2) as (
select date '2017-12-01', 1, 1, 1, 10, 10 from dual
union all select date '2018-01-01', 1, 1, 1, null, null from dual
union all select date '2018-02-01', 1, 1, 1, 20, 10 from dual
union all select date '2018-03-01', 1, 1, 1, 20, 10 from dual
union all select date '2018-04-01', 1, 1, 1, 10, 30 from dual
union all select date '2018-01-01', 2, 2, 2, 10, 20 from dual
union all select date '2018-03-01', 2, 2, 2, 10, 10 from dual
)
...
相同的查询得到:
MONTH ID1 ID2 ID3 VALUE1 VALUE2 QBD_VALUE1 QFD_VALUE2 QTR_VALUE
------ --- --- --- ------ ------ ---------- ---------- ----------
Dec-17 1 1 1 10 10 0 10 10
Jan-18 1 1 1 0 20 20
Feb-18 1 1 1 20 10 0 20 20
Mar-18 1 1 1 20 10 20 10 30
Apr-18 1 1 1 10 30 0 30 30
Jan-18 2 2 2 10 20 0 30 30
Mar-18 2 2 2 10 10 10 10 20
这似乎符合您的期望。
离开原来的问题,但看着不寻常的区域,你可以通过添加分析最小值和最大值来看到正在使用的月份(尽管如果还有缺失的月数,这些会让人感到困惑,所以我重新添加了May null值使它更清晰一点):
with your_table(month, id1, id2, id3, value1, value2) as (
select date '2017-12-01', 1, 1, 1, 10, 10 from dual
union all select date '2018-01-01', 1, 1, 1, null, null from dual
union all select date '2018-02-01', 1, 1, 1, 20, 10 from dual
union all select date '2018-03-01', 1, 1, 1, 20, 10 from dual
union all select date '2018-04-01', 1, 1, 1, 10, 30 from dual
union all select date '2018-05-01', 1, 1, 1, null, null from dual
union all select date '2018-01-01', 2, 2, 2, 10, 20 from dual
union all select date '2018-03-01', 2, 2, 2, 10, 10 from dual
)
select to_char(month, 'Mon-RR', 'nls_date_language=english') as month,
id1, id2, id3, value1, value2,
coalesce(sum(coalesce(value1, 0)) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between unbounded preceding and 1 preceding
), 0) as qbd_value1,
coalesce(sum(coalesce(value2, 0)) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between current row and unbounded following
), 0) as qfd_value2,
coalesce(sum(coalesce(value1, 0)) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between unbounded preceding and 1 preceding
), 0)
+
coalesce(sum(coalesce(value2, 0)) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between current row and unbounded following
), 0) as qtr_value,
to_char(min(month) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between unbounded preceding and current row
), 'Mon-RR', 'nls_date_language=english') as qtr_start,
to_char(max(month) over (
partition by id1, id2, id3, trunc(month, 'Q')
order by month
rows between current row and unbounded following
), 'Mon-RR', 'nls_date_language=english') as qtr_end
from your_table;
MONTH ID1 ID2 ID3 VALUE1 VALUE2 QBD_VALUE1 QFD_VALUE2 QTR_VALUE QTR_START QTR_END
------ --- --- --- ------ ------ ---------- ---------- ---------- --------------- ---------------
Dec-17 1 1 1 10 10 0 10 10 Dec-17 Dec-17
Jan-18 1 1 1 0 20 20 Jan-18 Mar-18
Feb-18 1 1 1 20 10 0 20 20 Jan-18 Mar-18
Mar-18 1 1 1 20 10 20 10 30 Jan-18 Mar-18
Apr-18 1 1 1 10 30 0 30 30 Apr-18 May-18
May-18 1 1 1 10 0 10 Apr-18 May-18
Jan-18 2 2 2 10 20 0 30 30 Jan-18 Mar-18
Mar-18 2 2 2 10 10 10 10 20 Jan-18 Mar-18
要获得调整范围,您可以在add_months()
调用中使用trunc()
,如评论中所述,在所有分析子句中:
with your_table(month, id1, id2, id3, value1, value2) as (
select date '2017-12-01', 1, 1, 1, 10, 10 from dual
union all select date '2018-01-01', 1, 1, 1, null, null from dual
union all select date '2018-02-01', 1, 1, 1, 20, 10 from dual
union all select date '2018-03-01', 1, 1, 1, 20, 10 from dual
union all select date '2018-04-01', 1, 1, 1, 10, 30 from dual
union all select date '2018-05-01', 1, 1, 1, null, null from dual
union all select date '2018-01-01', 2, 2, 2, 10, 20 from dual
union all select date '2018-03-01', 2, 2, 2, 10, 10 from dual
)
select to_char(month, 'Mon-RR', 'nls_date_language=english') as month,
id1, id2, id3, value1, value2,
coalesce(sum(coalesce(value1, 0)) over (
partition by id1, id2, id3, trunc(add_months(month, 1), 'Q')
order by month
rows between unbounded preceding and 1 preceding
), 0) as qbd_value1,
coalesce(sum(coalesce(value2, 0)) over (
partition by id1, id2, id3, trunc(add_months(month, 1), 'Q')
order by month
rows between current row and unbounded following
), 0) as qfd_value2,
coalesce(sum(coalesce(value1, 0)) over (
partition by id1, id2, id3, trunc(add_months(month, 1), 'Q')
order by month
rows between unbounded preceding and 1 preceding
), 0)
+
coalesce(sum(coalesce(value2, 0)) over (
partition by id1, id2, id3, trunc(add_months(month, 1), 'Q')
order by month
rows between current row and unbounded following
), 0) as qtr_value,
to_char(min(month) over (
partition by id1, id2, id3, trunc(add_months(month, 1), 'Q')
order by month
rows between unbounded preceding and current row
), 'Mon-RR', 'nls_date_language=english') as qtr_start,
to_char(max(month) over (
partition by id1, id2, id3, trunc(add_months(month, 1), 'Q')
order by month
rows between current row and unbounded following
), 'Mon-RR', 'nls_date_language=english') as qtr_end
from your_table;
MONTH ID1 ID2 ID3 VALUE1 VALUE2 QBD_VALUE1 QFD_VALUE2 QTR_VALUE QTR_START QTR_END
------ --- --- --- ------ ------ ---------- ---------- ---------- --------------- ---------------
Dec-17 1 1 1 10 10 0 20 20 Dec-17 Feb-18
Jan-18 1 1 1 10 10 20 Dec-17 Feb-18
Feb-18 1 1 1 20 10 10 10 20 Dec-17 Feb-18
Mar-18 1 1 1 20 10 0 40 40 Mar-18 May-18
Apr-18 1 1 1 10 30 20 30 50 Mar-18 May-18
May-18 1 1 1 30 0 30 Mar-18 May-18
Jan-18 2 2 2 10 20 0 20 20 Jan-18 Jan-18
Mar-18 2 2 2 10 10 0 10 10 Mar-18 Mar-18
答案 1 :(得分:0)
select
a.d month,nvl(id1,0) id1,nvl(id2,0) id2,nvl(id3,0) id3,nvl(value,0)value
from
( SELECT TO_CHAR(ADD_MONTHS(DATE '2018-01-01',(level-1)),'Mon-YY') d
FROM DUAL
CONNECT BY level < 13) a left join mytable
on a.d=mytable.month
如果有任何疑问 - http://sqlfiddle.com/#!4/7b8c7/14