いくつかの分析を使用してこれを行うことができます。
SQL> alter session set nls_date_format='yy/mm/dd';
Session altered.
SQL> select id, min(val) date_from, max(val) date_till
2 from (select id, val, max(grp) over(partition by id order by val) grp
3 from (select id, val, lag(val, 1) over(partition by id order by val),
4 case
5 when lag(val, 1) over(partition by id order by val) < val - 1 then
6 row_number() over(partition by id order by val)
7 when row_number() over(partition by id order by val) = 1 then
8 1
9 end grp
10 from mytab))
11 group by id, grp
12 order by id, date_from
13 /
ID DATE_FRO DATE_TIL
---------- -------- --------
9465 12/12/20 12/12/22
9465 12/12/25 12/12/26
9466 12/12/21 12/12/25
9466 12/12/27 12/12/27
つまり、最初に結果セットをグループに分割します。グループは、特定の ID の連続した日付として定義されます。これを行うには、前の日付をチェックし、その < 現在の行の日付 - 1 かどうかを確認します。lag(val, 1) over(partition by id order by val)
SQL> select id, val, lag(val, 1) over(partition by id order by val),
2 case
3 when lag(val, 1) over(partition by id order by val) < val - 1 then
4 row_number() over(partition by id order by val)
5 when row_number() over(partition by id order by val) = 1 then
6 1
7 end grp
8 from mytab
9 /
ID VAL LAG(VAL, GRP
---------- -------- -------- ----------
9465 12/12/20 1
9465 12/12/21 12/12/20
9465 12/12/22 12/12/21
9465 12/12/25 12/12/22 4
9465 12/12/26 12/12/25
9466 12/12/21 1
9466 12/12/22 12/12/21
9466 12/12/23 12/12/22
9466 12/12/24 12/12/23
9466 12/12/25 12/12/24
9466 12/12/27 12/12/25 6
11 rows selected.
次に空白を埋める必要があります。これにより、空白がその前の null 以外のグループに関連付けられます。つまり、ここでの順序でこれに max() を適用するとmax(grp) over(partition by id order by val)
、セット全体の最大ではなく、その時点までに表示された最大行のみが取得されることを意味します。
SQL> select id, val, max(grp) over(partition by id order by val) grp
2 from (select id, val, lag(val, 1) over(partition by id order by val),
3 case
4 when lag(val, 1) over(partition by id order by val) < val - 1 then
5 row_number() over(partition by id order by val)
6 when row_number() over(partition by id order by val) = 1 then
7 1
8 end grp
9 from mytab)
10 /
ID VAL GRP
---------- -------- ----------
9465 12/12/20 1
9465 12/12/21 1
9465 12/12/22 1
9465 12/12/25 4
9465 12/12/26 4
9466 12/12/21 1
9466 12/12/22 1
9466 12/12/23 1
9466 12/12/24 1
9466 12/12/25 1
9466 12/12/27 6
11 rows selected.
これで、(id, grp) による単純なグループが適用され、id+group ごとに min() と max() が取得されます。