我的表格定义如下
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;
几个月的错过,我在输出中得到一个无限循环
答案 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