我想递归地使用日期,但不能得到预期的结果

  • 本文关键字:结果 但不能 递归 日期 plsql
  • 更新时间 :
  • 英文 :

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. 给定初始输入日期,计算活动日期作为前一个月+1天(即2019年6月22日生产2019年5月23日
  2. 迭代总共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 ;                 

相关内容

最新更新