WITH t AS ( SELECT ADD_MONTHS(TO_DATE('201301', 'yyyymm'), LEVEL-1) dt FROM dual CONNECT BY LEVEL <= 12 ) SELECT TO_CHAR(dt, 'yyyymm') yyyymm , NEXT_DAY(TRUNC(dt, 'yy')-1, 2) y_1st_mon , NEXT_DAY(TRUNC(dt, 'q' )-1, 2) q_1st_mon , NEXT_DAY(TRUNC(dt, 'mm')-1, 2) m_1st_mon FROM t ; YYYYMM Y_1ST_MO Q_1ST_MO M_1ST_MO ------ -------- -------- -------- 201301 13/01/07 13/01/07 13/01/07 201302 13/01/07 13/01/07 13/02/04 201303 13/01/07 13/01/07 13/03/04 201304 13/01/07 13/04/01 13/04/01 201305 13/01/07 13/04/01 13/05/06 201306 13/01/07 13/04/01 13/06/03 201307 13/01/07 13/07/01 13/07/01 201308 13/01/07 13/07/01 13/08/05 201309 13/01/07 13/07/01 13/09/02 201310 13/01/07 13/10/07 13/10/07 201311 13/01/07 13/10/07 13/11/04 201312 13/01/07 13/10/07 13/12/02