以下设置代表产品连续几周的销售额。
22,19,20,23,16,14,15,15,18,21,24,10,17
... 每周销售表
date sales
week-1 : 22
week-2 : 19
week-3 : 20
...
week-12 : 10
week-13 : 17
我需要连续几周找到最长的高销售数字,即由14,15,15,18,21,24
代表的第6周到第11周。
我正在尝试使用递归CTE前进到下周,以查找销售额是否相等或更高。只要值相等或更高,继续移动到下一周,记录锚成员的ROWNUMBER(表示起始周数)和迭代行的周数。使用这种方法,有冗余的递归调用。例如,当第2周调用cte时,它会迭代第3周,第4周和第5周,因为销售价值比前一周的每周更高。现在,在第2周之后,应该在第5周调用cte,因为已经访问了第3周,第4周和第5周。
基本上,如果我已经在递归调用中访问了一行filt_coll
,我不希望它再次传递给CTE。标识为冗余的行不应找到,actualweek
列的值应该是唯一的。
我知道下面的sql没有解决我找到最长的较高值的问题。我可以从startweek
列的最大数量计算出来。目前,我正在试图找出如何消除冗余递归调用。
START_WEEK | SALES | SALESLAG | SALESLEAD | ACTUALWEEK
1 | 22 | 0 | -3 | 1
2 | 19 | -3 | 1 | 2
2 | 20 | 1 | 3 | 3
2 | 23 | 3 | -7 | 4
3 | 20 | 1 | 3 | 3 <-(redundant)
3 | 23 | 3 | -7 | 4 <-(redundant)
4 | 23 | 3 | -7 | 4 <-(redundant)
6 | 14 | -2 | 1 | 6
...
with
-- begin test data
raw_data (sales) as
(
select '22,19,20,23,16,14,15,15,18,21,24,10,17' from dual
)
,
derived_tbl(week, sales) as
(
select level, regexp_substr(sales, '([[:digit:]]+)(,|$)', 1, level, null, 1)
from raw_data connect by level <= regexp_count(sales,',')+1
)
-- end test data
,
coll(week, sales, saleslag, saleslead) as
(
select week, sales,
nvl(sales - (lag(sales) over (order by week)), 0),
nvl((lead(sales) over (order by week) - sales), 0)
from derived_tbl
)
,
filt_coll(week, sales, saleslag, saleslead) as
(
select week, sales, saleslag, saleslead
from coll
where not (saleslag < 0 and saleslead < 0)
)
,
cte(startweek, sales, saleslag, saleslead, actualweek) as
(
select week, sales, saleslag, saleslead, week from filt_coll
-- where week not in (select week from cte)
-- *** want to achieve the effect of the above commented out line
union all
select cte.startweek, cl.sales, cl.saleslag, cl.saleslead, cl.week
from filt_coll cl, cte
where cl.week = cte.actualweek + 1 and cl.sales >= cte.sales
)
select * from cte
order by 1,actualweek
;