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

Plsql 我想递归地使用date,但不能得到预期的结果,plsql,Plsql,我希望递归地使用给定的日期不到1个月,并且我已经基于上述输入编写了上述查询,以实现以下输出。 我给出了输入日期“2019年6月22日”,希望继续迭代到2019年5月24日,然后迭代2应从“2019年5月23日”开始,并继续此迭代到2019年4月26日,依此类推迭代3和4 要考虑1个月21 / 06 /2019,7/10/2019,24/4/2019 想考虑2个月10/5/2019、26/04、2019 想考虑3个月12/4 /2019,29 / 03 / 2019 想考虑4个月15 / 03 /

我希望递归地使用给定的日期不到1个月,并且我已经基于上述输入编写了上述查询,以实现以下输出。 我给出了输入日期“2019年6月22日”,希望继续迭代到2019年5月24日,然后迭代2应从“2019年5月23日”开始,并继续此迭代到2019年4月26日,依此类推迭代3和4

要考虑1个月21 / 06 /2019,7/10/2019,24/4/2019 想考虑2个月10/5/2019、26/04、2019 想考虑3个月12/4 /2019,29 / 03 / 2019 想考虑4个月15 / 03 / 2019 预期产出:


首先,您仍然缺少表定义DDL,输入输出上的列标题不定义表。此外,还存在一致性问题。您的查询引用了帐号,但您的示例数据和输出都没有引用帐号。您的查询还连接表det和ele,但在描述中没有提到这两个表

最后,您的预期输出包含两列amt、rank/group,但它们都不存在于输入中,因此无法输出。但是,您的查询也不包含它们。没有任何真正的表格描述,我自己做了

+---+-------+-------------+---+--------------+----------------+------------+-----+-------------+ 
|   |   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         | 
+---+-------+-------------+---+--------------+----------------+------------+-----+-------------+
您对所需内容的描述需要更多信息。你说你得到的日期是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,该列不在您的预期输出中,并将两列ant、rank/group添加到不在查询中的输出中。 因此,我将返回相同的结果,但是添加到您可能需要过滤的循环cyc中,因为您没有提到您感兴趣的迭代。但是CTE应该向您展示如何使用递归CTE

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;  

请努力解决您的问题,而不仅仅是复制和粘贴。展示你做了什么,清楚地问你的问题。这里的社区不会做你的家庭作业。看。格式化你的代码,使用,不要发布图片,把预期的结果放在问题中,必要时更新问题。现在已经一个多星期了。如果答案解决了你的问题,请接受它,如果没有,那么剩下的问题是什么?如果需要,不要将问题挂起,删除并发布新问题。这看起来非常有用,尽管我想说的是,为普通读者编写答案比只写专栏文章要好。我删除了与答案格式相关的评论,因为这会稀释读者最想看的内容。一般来说,如果你认为一个问题还没有准备好回答,回答其他问题,或者通过添加评论帮助OP回答他们的问题。这里非常欢迎格式/投票评论。不幸的是,大多数1-rep用户不会回来与他们的助手互动——如果您愿意,您可以在问题下发送一个快速提醒,但根据我的经验,这样做没有多大意义。您可以在他们的配置文件中看到他们上次登录的时间戳。
+---+-------+-------------+---+--------------+----------------+------------+-----+-------------+ 
|   |   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         | 
+---+-------+-------------+---+--------------+----------------+------------+-----+-------------+
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;  
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 ;