在开始和结束时段之间设置范围

时间:2017-10-09 16:24:12

标签: sql oracle

参数表,由用户维护:

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

2 个答案:

答案 0 :(得分: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;  

答案 1 :(得分: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;