2017-10-09 70 views
0

参数表的范围内,将由用户来维护:使开始和结束期间

PERIOD_ID START_PERIOD END_PERIOD 
BU201701 201701   201712 

最终的结果,我想剧本后看到的内容:

KEY   PERIOD PLAN_PERIOD 
BU201701 201701 201701 
BU201701 201702 201701 
BU201701 201703 201701 
BU201701 201704 201701 
BU201701 201705 201701 
BU201701 201706 201701 
BU201701 201707 201701 
BU201701 201708 201701 
BU201701 201709 201701 
BU201701 201710 201701 
BU201701 201711 201701 
BU201701 201712 201701 
BU201701 201701 201702 
BU201701 201702 201702 
BU201701 201703 201702 
BU201701 201704 201702 
BU201701 201705 201702 
BU201701 201706 201702 
BU201701 201707 201702 
BU201701 201708 201702 
BU201701 201709 201702 
BU201701 201710 201702 
BU201701 201711 201702 
BU201701 201712 201702 
BU201701 201701 201703 
BU201701 201702 201703 
BU201701 201703 201703 
BU201701 201704 201703 
BU201701 201705 201703 
BU201701 201706 201703 
BU201701 201707 201703 
BU201701 201708 201703 
BU201701 201709 201703 
BU201701 201710 201703 
BU201701 201711 201703 
BU201701 201712 201703 
BU201701 201701 201704 
BU201701 201702 201704 
BU201701 201703 201704 
BU201701 201704 201704 
BU201701 201705 201704 
BU201701 201706 201704 
BU201701 201707 201704 
BU201701 201708 201704 
BU201701 201709 201704 
BU201701 201710 201704 
BU201701 201711 201704 
BU201701 201712 201704 
BU201701 201701 201705 
BU201701 201702 201705 
BU201701 201703 201705 
BU201701 201704 201705 
BU201701 201705 201705 
BU201701 201706 201705 
BU201701 201707 201705 
BU201701 201708 201705 
BU201701 201709 201705 
BU201701 201710 201705 
BU201701 201711 201705 
BU201701 201712 201705 
.......... 
BU201701 201701 201712 
BU201701 201702 201712 
BU201701 201703 201712 
BU201701 201704 201712 
BU201701 201705 201712 
BU201701 201706 201712 
BU201701 201707 201712 
BU201701 201708 201712 
BU201701 201709 201712 
BU201701 201710 201712 
BU201701 201711 201712 
BU201701 201712 201712 

代码我曾尝试没有成功:

with data as (
       SELECT 
       to_char(to_date(FROM_PERIOD,'YYYYMM'),'YYYYMM') as FROM_PERIOD, 
       to_char(to_date(TO_PERIOD,'YYYYMM'),'YYYYMM') as TO_PERIOD, 
       to_char(to_date(FROM_PERIOD,'YYYYMM'),'YYYYMM') as DT 
       FROM SOR_MAP_PLAN_PERIOD 
       UNION ALL 
       SELECT 
       to_char(to_date(FROM_PERIOD,'YYYYMM'),'YYYYMM') as FROM_PERIOD, 
       to_char(to_date(TO_PERIOD,'YYYYMM'),'YYYYMM') as TO_PERIOD, 
       cast(to_char(to_date(FROM_PERIOD,'YYYYMM'),'YYYYMM')+1 as varchar(20)) as DT 
       FROM SOR_MAP_PLAN_PERIOD 
       WHERE cast(to_char(to_date(FROM_PERIOD,'YYYYMM'),'YYYYMM')+1 as varchar(20)) <= to_char(to_date(TO_PERIOD,'YYYYMM'),'YYYYMM') 
      ) 
    select 
    FROM_PERIOD, 
    TO_PERIOD, 
    DT 

回答

1

您可以使用CROSS JOIN

WITH p (period_id, start_period, end_period) 
    AS (SELECT 'BU201701', 
       To_date('201701', 'YYYYMM'), 
       To_date('201712', 'YYYYMM') 
     FROM dual), 
    date_ranges 
    AS (SELECT period_id, 
       To_char(start_period, 'YYYYMM') 
       START_PERIOD, 
       To_char(Add_months (start_period, LEVEL - 1), 'YYYYMM') 
       END_PERIOD 
     FROM p 
     CONNECT BY LEVEL <= Months_between(end_period, start_period) + 1) 
SELECT d.period_id as "KEY", 
     d.end_period as "PERIOD", 
     e.end_period as "PLAN_PERIOD" 
FROM date_ranges d 
     cross join (SELECT end_period 
        FROM date_ranges) e 
ORDER BY 3, 
      2; 
+0

还有一个问题:如果在参数表中添加更多的period_id。如何修改交叉连接以重复记录。例如PERIOD_ID START_PERIOD END_PERIOD BU201701 201701 201712 201801 STR201801 201812 –

+0

我建议你问,作为一个单独的问题提供链接到这个问题,以帮助了解背景。 –

0

我写了一个类似的答案@Kaushik,反正共享,因为我认为差异是有趣的。

with param_table as (select 'BU201701' as period_id, 201701 as start_period, 
        201712 as end_period from dual), 
    period_list as (select start_period+(level-1) as period 
        from param_table 
        connect by level <= (end_period - start_period)) 
select period_id, p1.period as period, p2.period as plan_period 
from param_table 
    cross join period_list p1 
    cross join period_list p2 
order by 3, 2; 
+1

如果'start_period'和'end_period'在2年不同,这将失败。 –

+0

非常感谢它的作品!如果开始和结束时间在两年内,我需要考虑的事项。 –

+0

还有一个问题:如果在参数表中添加更多的period_id。如何修改交叉连接以重复记录。例如PERIOD_ID START_PERIOD END_PERIOD BU201701 201701 201712 201801 STR201801 201812 –