WITH CTE_Dates(seqno,
account_no,
subacc_no,
date1,
input_date,
act_date,
arrears_os) AS
(SELECT seqno,
account_no,
subacc_no,
date1,
TO_DATE('22-JUN-2019', 'DD-MON-YYYY') input_date,
(ADD_MONTHS(TO_DATE('22-JUN-2019', 'DD-MON-YYYY'), -1) + 1) act_date,
arrears_os
FROM det pd, ele pe
WHERE pd.account_no = pe.account_no
UNION ALL
SELECT seqno,
account_no,
subacc_no,
date1,
TO_DATE('22-JUN-2019', 'DD-MON-YYYY') input_date,
(ADD_MONTHS(TO_DATE('22-JUN-2019', 'DD-MON-YYYY'), -1) + 1) act_date,
arrears_os
FROM CTE_Dates
WHERE ADD_MONTHS(TRUNC(input_date, 'MONTH'), 1) <=
TO_DATE('22-JUN-2019', 'DD-MON-YYYY')
)
SELECT seqno,
account_no,
subacc_no,
date1,
input_date,
act_date,
arrears_os,
CASE
WHEN date1 BETWEEN act_date AND input_date THEN
input_date
ELSE
(ADD_MONTHS(input_date, -1))
END new_input_dt
from CTE_Dates
ORDER BY date1 DESC
输入:
+----+----------+-------+-------------+---+------------+-----+
| | A | B | C | D | E | F |
+----+----------+-------+-------------+---+------------+-----+
| 1 | Current | | | | | |
| 2 | 0 | seqno | subacc_no | | date1 | |
| 3 | 1 | 709 | M223355 | 1 | 21/06/2019 | |
| 4 | 2 | 709 | M223355 | 1 | 7/6/2019 | |
| 5 | 3 | 709 | M223355 | 1 | 24/05/2019 | |
| 6 | 4 | 709 | M223355 | 1 | 10/5/2019 | |
| 7 | 5 | 709 | M223355 | 1 | 26/04/2019 | |
| 8 | 6 | 709 | M223355 | 1 | 12/4/2019 | |
| 9 | 7 | 709 | M223355 | 1 | 29/03/2019 | |
| 10 | 8 | 709 | M223355 | 1 | 15/03/2019 | |
+----+----------+-------+-------------+---+------------+-----+
我想递归地使用我的给定日期(不到1个月(,并且我已经根据上面提到的输入编写了上面的查询,以实现下面的输出
我给出的输入日期为"2019年6月22日"。如果要继续迭代到日期1(2019年5月24日(,则迭代2应从"2019年5月份23日"开始,并继续此迭代到日期(2019年4月26日(,依此类推迭代3和4。
- 想要考虑1个月(2019年6月21日,2019年7月6日,2019 2019年5月24日
- 想考虑2个月(2019年5月10日,2019年4月26日(
- 想考虑3个月(2019年4月12日,2019年3月29日(
- 想考虑4个月(2019年3月15日(
预期输出:
+---+-------+-------------+---+--------------+----------------+------------+-----+-------------+
| | A | B | C | D | E | F | G | H |
+---+-------+-------------+---+--------------+----------------+------------+-----+-------------+
| 1 | seqno | subacc_no | | date1 | input_date | act_date | amt | rank/group |
| 2 | 709 | M223355 | 1 | 21/06/2019 | 22/06/2019 | 23/05/2019 | 200 | 1 |
| 3 | 709 | M223355 | 1 | 7/6/2019 | 22/06/2019 | 23/05/2019 | 200 | 1 |
| 4 | 709 | M223355 | 1 | 24/05/2019 | 22/06/2019 | 23/05/2019 | 200 | 1 |
| 5 | 709 | M223355 | 1 | 10/5/2019 | 22/05/2019 | 23/04/2019 | 200 | 2 |
| 6 | 709 | M223355 | 1 | 26/04/2019 | 22/05/2019 | 23/04/2019 | 200 | 2 |
| 7 | 709 | M223355 | 1 | 12/4/2019 | 22/04/2019 | 23/03/2019 | 200 | 3 |
| 8 | 709 | M223355 | 1 | 29/03/2019 | 22/04/2019 | 23/03/2019 | 200 | 3 |
| 9 | 709 | M223355 | 1 | 15/03/2019 | 22/03/2019 | 23/02/2019 | 200 | 4 |
+---+-------+-------------+---+--------------+----------------+------------+-----+-------------+
首先,您仍然缺少表定义(DDL(,输入输出上的列标题并没有定义表。此外,您还存在一致性问题。您的查询引用了account_number,但您的样本数据和输出都没有引用。您的查询还连接了表det和ele,但在描述中都没有提到。
最后,您期望的输出包含2列(amt、rank/group(,但输入中都不存在,因此无法输出。但是,您的查询都不包含它们。由于没有任何真实的表格描述,我自己做了。
create table det (
seqno integer,
account_no integer,
subacc_no varchar(20),
d integer,
date1 date ,
arrears_os varchar2(20)
);
insert into det(seqno, account_no, subacc_no,d,date1)
select 1, 709, 'M223355', 1, to_date('21/06/2019', 'FMdd/mm/yyyy') from dual union all
select 2, 709, 'M223355', 1, to_date('07/06/2019', 'FMdd/mm/yyyy') from dual union all
select 3, 709, 'M223355', 1, to_date('24/05/2019', 'FMdd/mm/yyyy') from dual union all
select 4, 709, 'M223355', 1, to_date('10/05/2019', 'FMdd/mm/yyyy') from dual union all
select 5, 709, 'M223355', 1, to_date('26/04/2019', 'FMdd/mm/yyyy') from dual union all
select 6, 709, 'M223355', 1, to_date('12/04/2019', 'FMdd/mm/yyyy') from dual union all
select 7, 709, 'M223355', 1, to_date('29/03/2019', 'FMdd/mm/yyyy') from dual union all
select 8, 709, 'M223355', 1, to_date('15/03/2019', 'FMdd/mm/yyyy') from dual ;
create table ele as
select distinct account_no from det;
您对所需内容的描述需要更多信息。你说你得到的日期是2019年6月22日,迭代回2019年5月24日,是按天还是按月迭代。第二次迭代从2019年5月23日开始,到4月26日结束?
然后你想考虑几个月:1个月,但你列出了3个月(我想我可能掉了1个月(;2个月,但列出3,2个月但列出2,4个月但列1。列出的日期似乎只是随机的。至少我找不到模式。
现在开始查询。我假设你在描述中尝试的是:
- 给定初始输入日期,计算活动日期作为前一个月+1天(即2019年6月22日生产2019年5月23日
- 迭代总共4个周期,每次迭代都使用之前计算的活动日期作为输入日期
我不知道你的主查询试图做什么。你引入了一个不在预期输出中的列(new_input_dt(,并向不在查询中的输出添加了2列(ant、rank/group(。因此,我将返回相同的结果,但添加到您可能需要筛选的循环(cyc(中,因为您没有提到您感兴趣的迭代。但是CTE应该向您展示如何使用递归CTE。
with cte_dates (account_no,input_date, act_date, cyc) as
( select account_no
, to_date('22-JUN-2019', 'dd-mon-yyyy') input_date
, (add_months(to_date('22-JUN-2019', 'dd-mon-yyyy'), -1) + 1) act_date
, 1 cyc
from ele
union all
select account_no
, act_date
, add_months(act_date, -1) + 1
, cyc + 1
from cte_dates
where cyc+1 <= 4
)
select pd.seqno,
pd.account_no,
pd. subacc_no,
pd.d -- D on input, C on output descriptions?
pd. date1,
cte.input_date,
cte.act_date,
pd.arrears_os,
case
when pd.date1 between cte.act_date and cte.input_date
then cte.input_date
else add_months(cte.input_date, -1)
end new_input_dt,
cte.cyc
from cte_dates cte
join det pd on (pd.account_no = cte.account_no)
order by date1 desc ;