Tabibitosan Method: Example 2
Grouping consecutive month range without gaps
SQL> create table ex100
2 as
3 select date '2013-01-01' dt from dual union all
4 select date '2013-02-01' from dual union all
5 select date '2013-03-01' from dual union all
6 select date '2013-06-01' from dual union all
7 select date '2013-07-01' from dual union all
8 select date '2013-10-01' from dual union all
9 select date '2013-12-01' from dual union all
10 select date '2014-01-01' from dual
11 /
Table created.
SQL> select * from ex100;
DT
---------
01-JAN-13
01-FEB-13
01-MAR-13
01-JUN-13
01-JUL-13
01-OCT-13
01-DEC-13
01-JAN-14
8 rows selected.
Expected result:
01-JAN-13 01-MAR-13
01-JUN-13 01-JUL-13
01-OCT-13 01-OCT-13
01-DEC-13 01-JAN-14
ie, group by consective month range without gaps.
SQL> select dt,
2 extract(year from dt)*12
3 +extract(month from dt),
4 row_number()over (order by dt) rn,
5 extract(year from dt)*12
6 + extract(month from dt)
7 - row_number()over (order by dt) grp
8 from ex100;
DT EXTRACT(YEARFROMDT)*12+EXTRACT(MONTHFROMDT) RN GRP
--------- ------------------------------------------- ---------- ----------
01-JAN-13 24157 1 24156
01-FEB-13 24158 2 24156
01-MAR-13 24159 3 24156
01-JUN-13 24162 4 24158
01-JUL-13 24163 5 24158
01-OCT-13 24166 6 24160
01-DEC-13 24168 7 24161
01-JAN-14 24169 8 24161
8 rows selected.
SQL> select min(dt), max(dt)
2 from (
3 select dt,
4 extract(year from dt)*12
5 +extract(month from dt),
6 row_number()over (order by dt) rn,
7 extract(year from dt)*12
8 + extract(month from dt)
9 - row_number()over (order by dt) grp
10 from ex100)
11 group by grp
12 order by min(dt);
MIN(DT) MAX(DT)
--------- ---------
01-JAN-13 01-MAR-13
01-JUN-13 01-JUL-13
01-OCT-13 01-OCT-13
01-DEC-13 01-JAN-14
or,get the count of months from an initial month say '01-01-1900'
SQL> select dt,
2 months_between(dt, to_date('01/01/1900','dd/mm/yyyy')),
3 row_number()over (order by dt) rn
4 from ex100;
DT MONTHS_BETWEEN(DT,TO_DATE('01/01/1900','DD/MM/YYYY')) RN
--------- ----------------------------------------------------- ----------
01-JAN-13 1356 1
01-FEB-13 1357 2
01-MAR-13 1358 3
01-JUN-13 1361 4
01-JUL-13 1362 5
01-OCT-13 1365 6
01-DEC-13 1367 7
01-JAN-14 1368 8
8 rows selected.
SQL> select min(dt), max(dt)
2 from (
3 select dt,
4 months_between(dt, to_date('01/01/1900','dd/mm/yyyy'))
5 -row_number()over (order by dt) grp
6 from ex100)
7 group by grp
8 order by min(dt);
MIN(DT) MAX(DT)
--------- ---------
01-JAN-13 01-MAR-13
01-JUN-13 01-JUL-13
01-OCT-13 01-OCT-13
01-DEC-13 01-JAN-14
Grouping consecutive month range without gaps
SQL> create table ex100
2 as
3 select date '2013-01-01' dt from dual union all
4 select date '2013-02-01' from dual union all
5 select date '2013-03-01' from dual union all
6 select date '2013-06-01' from dual union all
7 select date '2013-07-01' from dual union all
8 select date '2013-10-01' from dual union all
9 select date '2013-12-01' from dual union all
10 select date '2014-01-01' from dual
11 /
Table created.
SQL> select * from ex100;
DT
---------
01-JAN-13
01-FEB-13
01-MAR-13
01-JUN-13
01-JUL-13
01-OCT-13
01-DEC-13
01-JAN-14
8 rows selected.
Expected result:
01-JAN-13 01-MAR-13
01-JUN-13 01-JUL-13
01-OCT-13 01-OCT-13
01-DEC-13 01-JAN-14
ie, group by consective month range without gaps.
SQL> select dt,
2 extract(year from dt)*12
3 +extract(month from dt),
4 row_number()over (order by dt) rn,
5 extract(year from dt)*12
6 + extract(month from dt)
7 - row_number()over (order by dt) grp
8 from ex100;
DT EXTRACT(YEARFROMDT)*12+EXTRACT(MONTHFROMDT) RN GRP
--------- ------------------------------------------- ---------- ----------
01-JAN-13 24157 1 24156
01-FEB-13 24158 2 24156
01-MAR-13 24159 3 24156
01-JUN-13 24162 4 24158
01-JUL-13 24163 5 24158
01-OCT-13 24166 6 24160
01-DEC-13 24168 7 24161
01-JAN-14 24169 8 24161
8 rows selected.
SQL> select min(dt), max(dt)
2 from (
3 select dt,
4 extract(year from dt)*12
5 +extract(month from dt),
6 row_number()over (order by dt) rn,
7 extract(year from dt)*12
8 + extract(month from dt)
9 - row_number()over (order by dt) grp
10 from ex100)
11 group by grp
12 order by min(dt);
MIN(DT) MAX(DT)
--------- ---------
01-JAN-13 01-MAR-13
01-JUN-13 01-JUL-13
01-OCT-13 01-OCT-13
01-DEC-13 01-JAN-14
or,get the count of months from an initial month say '01-01-1900'
SQL> select dt,
2 months_between(dt, to_date('01/01/1900','dd/mm/yyyy')),
3 row_number()over (order by dt) rn
4 from ex100;
DT MONTHS_BETWEEN(DT,TO_DATE('01/01/1900','DD/MM/YYYY')) RN
--------- ----------------------------------------------------- ----------
01-JAN-13 1356 1
01-FEB-13 1357 2
01-MAR-13 1358 3
01-JUN-13 1361 4
01-JUL-13 1362 5
01-OCT-13 1365 6
01-DEC-13 1367 7
01-JAN-14 1368 8
8 rows selected.
SQL> select min(dt), max(dt)
2 from (
3 select dt,
4 months_between(dt, to_date('01/01/1900','dd/mm/yyyy'))
5 -row_number()over (order by dt) grp
6 from ex100)
7 group by grp
8 order by min(dt);
MIN(DT) MAX(DT)
--------- ---------
01-JAN-13 01-MAR-13
01-JUN-13 01-JUL-13
01-OCT-13 01-OCT-13
01-DEC-13 01-JAN-14
No comments:
Post a Comment