Ini cara yang bagus, nama bagus "Metode Tabibitosan " diberikan oleh Aketi Jyuuzou.
SQL> WITH data AS
2 (SELECT num - DENSE_RANK() OVER(PARTITION BY status ORDER BY num) grp,
3 status,
4 num
5 FROM t
6 )
7 SELECT MIN(num)
8 ||' - '
9 || MAX(num) range,
10 COUNT(*) cnt
11 FROM data
12 WHERE status='A'
13 GROUP BY grp
14 ORDER BY grp
15 /
RANGE CNT
------ ----------
1 - 3 3
6 - 6 1
9 - 10 2
SQL>
Catatan Lebih baik menggunakan DENSE_RANK
untuk menghindari duplikat.
Tabel
SQL> SELECT * FROM t ORDER BY num;
NUM S
---------- -
1 A
1 A
2 A
2 A
3 A
4 U
5 U
6 A
7 U
8 U
9 A
NUM S
---------- -
10 A
12 rows selected.
Ada duplikat untuk num =1.
Menggunakan DENSE_RANK :
SQL> WITH data AS
2 (SELECT num - DENSE_RANK() OVER(PARTITION BY status ORDER BY num) grp,
3 status,
4 num
5 FROM t
6 )
7 SELECT MIN(num)
8 ||' - '
9 || MAX(num) range,
10 COUNT(*) cnt
11 FROM data
12 WHERE status='A'
13 GROUP BY grp
14 ORDER BY grp
15 /
RANGE CNT
------ ----------
1 - 3 5
6 - 6 1
9 - 10 2
SQL>
Menggunakan ROW_NUMBER :
SQL> WITH DATA AS
2 (SELECT num - ROW_NUMBER() OVER(PARTITION BY status ORDER BY num) grp,
3 status,
4 num
5 FROM t
6 )
7 SELECT MIN(num)
8 ||' - '
9 || MAX(num) range,
10 COUNT(*) cnt
11 FROM data
12 WHERE status='A'
13 GROUP BY grp
14 ORDER BY grp
15 /
RANGE CNT
------ ----------
2 - 3 2
1 - 2 2
1 - 6 2
9 - 10 2
SQL>
Jadi, jika terjadi duplikat, ROW_NUMBER query akan memberikan hasil yang salah. Anda harus menggunakan DENSE_RANK .