月份错误列表

时间:2018-05-16 18:28:42

标签: sql oracle

我的表格定义如下

create table test (
    m_year varchar2(10),
    val number
);

数据看起来像

myear   val
Jan 10  876
Sep 10  709
Jan 11  46
Apr 11  99
Jan 12  878

我希望输出为

01-Jan-10 876
01-Feb-10 876
'
'
'
01-Sep-10 709
'
'
'
sysdate 878

我的查询看起来像

select to_char(add_months(myear,level-1)) months,val
from (
    select val, to_date(myear,'mm-yyyy') myear,
           lead(to_date(myear,'mm-yyyy'),1,sysdate) over (order by to_date(myear,'mm-yyyy')) as nxt
    from test
)
connect by level <= months_between(nxt,myear)+1;

几个月的错过,我在输出中得到一个无限循环

2 个答案:

答案 0 :(得分:0)

这是一个选项:

SQL> create table test
  2    (m_year varchar2(10),
  3     val    number);

Table created.

SQL> insert into test
  2    select 'Jan 10', 876 from dual union
  3    select 'Sep 10', 709 from dual union
  4    select 'Jan 11', 46  from dual union
  5    select 'Apr 11', 99  from dual union
  6    select 'Jan 12', 878 from dual;

5 rows created.

查询:

SQL> with
  2  dates as
  3    (select to_date(m_year, 'mon rr', 'nls_date_language = english') m_year,
  4            val
  5     from test
  6    ),
  7  whole_period as
  8    (select add_months(min_year, level - 1) m_year
  9     from (select min(m_year) min_year,
 10                 trunc(sysdate, 'mm') max_year
 11           from dates
 12          )
 13     connect by level <= months_between(max_year, min_year) + 1
 14    )
 15  select
 16    w.m_year,
 17    last_value(d.val) ignore nulls over
 18      (order by w.m_year rows between unbounded preceding and current row) val
 19  from whole_period w left join dates d on d.m_year = w.m_year
 20  order by w.m_year;

M_YEAR            VAL
---------- ----------
01.01.2010        876
01.02.2010        876
01.03.2010        876
01.04.2010        876
01.05.2010        876
01.06.2010        876
01.07.2010        876
01.08.2010        876
01.09.2010        709
01.10.2010        709
01.11.2010        709
01.12.2010        709
01.01.2011         46
01.02.2011         46
01.03.2011         46
01.04.2011         99
01.05.2011         99
01.06.2011         99
01.07.2011         99
01.08.2011         99
01.09.2011         99
01.10.2011         99
01.11.2011         99
01.12.2011         99
01.01.2012        878
01.02.2012        878
01.03.2012        878
<snip>
01.03.2018        878
01.04.2018        878
01.05.2018        878

101 rows selected.

SQL>

答案 1 :(得分:0)

做同样的懒惰方式 - 易于阅读,易于维护。不同可能会降低性能。 下次请将您的测试数据和结构添加到您的帖子中。你会得到更快的答案。

SELECT DISTINCT add_months(start_date, LEVEL-1) final_date
     , start_date
     , end_month
  FROM
(
SELECT to_date(myear) start_date 
     , LAG(to_date(myear)) OVER (ORDER BY myear DESC) end_date
     , MIN(EXTRACT(MONTH FROM myear)) OVER (ORDER BY myear) start_month
     , MAX(EXTRACT(MONTH FROM myear)) OVER (ORDER BY myear DESC) end_month
     , ROW_NUMBER() OVER (PARTITION BY EXTRACT(YEAR FROM myear) 
                              ORDER BY EXTRACT(YEAR FROM myear))  rno
  FROM
(
SELECT to_date('01-2010', 'mm-yyyy') myear FROM dual
UNION ALL
SELECT to_date('09-2010', 'mm-yyyy') FROM dual
UNION ALL
SELECT to_date('01-2011', 'mm-yyyy') FROM dual
UNION ALL
SELECT to_date('04-2011', 'mm-yyyy') FROM dual
)
)
WHERE rno = 1
CONNECT BY LEVEL <= end_month
ORDER BY start_date
/

FINAL DATE  START DATE  END MONTH
----------------------------------
01-JAN-10   01-JAN-10   9
01-FEB-10   01-JAN-10   9
01-MAR-10   01-JAN-10   9
01-APR-10   01-JAN-10   9
01-MAY-10   01-JAN-10   9
01-JUN-10   01-JAN-10   9
01-JUL-10   01-JAN-10   9
01-AUG-10   01-JAN-10   9
01-SEP-10   01-JAN-10   9
01-JAN-11   01-JAN-11   4
01-FEB-11   01-JAN-11   4
01-MAR-11   01-JAN-11   4
01-APR-11   01-JAN-11   4