level로 기간을 만들수 있나요? 0 6 2,427

by 바람이불면 [SQL Query] level connect by [2012.10.17 10:10:38]


안녕하세요 늘 도움을 잘 받아가고 있는 바람이불면 입니다. 

이번에 드릴 질문은...

period    value
==========
2012-03 4000
2012-08 6000

와 같은 data가 있을 때, 
period    value
==========
2012-01 4000
2012-02 4000
2012-03 4000
     :
2012-08 6000
     :
2012-12 6000
2013-01 6000
     :
2013-12 6000

이렇게 표시를 하고자 합니다. 

어떻게 하면 좋을까요? 
by 아발란체 [2012.10.17 11:31:21]
WITH T1 AS (
    SELECT '2012-03' AS period, '4000' AS value FROM DUAL
), T2 AS (
    SELECT LEVEL AS month FROM DUAL CONNECT BY LEVEL <= 24
)
SELECT
    ADD_MONTHS(TO_DATE(CONCAT(SUBSTR(period, 0, 4), '-01-01')), month - 1) AS val
FROM
    T1, T2


분석은 셀프레영~

by 손님 [2012.10.17 12:02:54]

SELECT CNT,
   YYMM,
   CASE WHEN YYMM <= '2012-03' THEN 4000
   ELSE 8000 END AS VALUE
  FROM (SELECT LEVEL AS CNT, TO_CHAR(ADD_MONTHS('2012-01-01', LEVEL - 1), 'YYYY-MM') AS YYMM
  FROM DUAL
    CONNECT BY LEVEL <= (MONTHS_BETWEEN ('20131201', '20120101') + 1)
   ) TT

맞나 모르겠네요.. 저도 초짜라.. 죄송합니다..

by 아발란체 [2012.10.17 13:24:28]

엉....제시 데이타셋과 결과 데이타셋 내용이 바뀌었네용...
그럼 제가 답단 것은 패스~ !

손님이 달아준 것이 답이네요.
저기서 2012-03를 2012-07로 바꿔주시면 되겠네요.
손님도 돌려보신거 같은데, 내용이 그사이 또 수정되었나보네요.


by 오케클릭 [2012.10.17 13:38:58]
 
WITH t(period, value) as (
select '2012-03','4000' from dual union all
select '2012-08','8000' from dual
)
select tm.dt as period
   , nvl(
      last_value(value ignore nulls) over(order by tm.dt),
      last_value(value ignore nulls) over(order by tm.dt desc)
     ) value 
from (
   select 
    to_char(add_months(
      (select 
        to_date(substr(min(period),1,4)||'01','yyyymm') 
        from t
      )
    ,level-1),'yyyy-mm') dt, level lv 
   from dual connect by level <= 24
  ) tm
left outer join t on t.period = tm.dt
order by dt

by 바람이불면 [2012.10.17 14:22:54]
아발란체님 : 아까 수정전에 달아주셨네요 에궁.. 감사합니다~ (__)
손님 님 : 감사하구요 그런데 사이사이에 다른 값들이 끼어있어서 작업해주신것은 사용하기가 조금 힘들 듯 합니다. 
오케클릭 님 : 감사하구요 9i라 ignore nulls를 못쓰지만 소중한 힌트 주셔서 답변 채택해드립니다~ 감사합니다~

by 오케클릭 [2012.10.17 17:33:24]
-- last_value 함수 쓰지 않은 쿼리 입니다.
WITH t(period, value) as ( 
select '2012-03','4000' from dual union all
select '2012-08','8000' from dual union all
select '2012-11','2000' from dual
) 
select TA.dt as period, TB.value from ( 
  select tm.dt 
    , t.value
    , nvl(nvl2(t.value, period,
     (select max(period) from t 
      where to_date(period,'yyyy-mm') < to_date(tm.dt,'yyyy-mm'))
     ),(select min(period) from t)) n_dt
  from ( 
    select 
    to_char(add_months( 
     (select 
      to_date(substr(min(period),1,4)||'01','yyyymm') 
      from t 
     ) 
    ,level-1),'yyyy-mm') dt, level lv 
    from dual connect by level <= 24 
   ) tm 
  left outer join t on t.period = tm.dt 
  order by dt
) TA
left outer join t TB on TB.period = TA.n_dt
order by dt
댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입