Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>we can do this with a couple of analytics:</p> <pre><code>SQL&gt; alter session set nls_date_format='yy/mm/dd'; Session altered. SQL&gt; 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) &lt; 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 </code></pre> <p>i.e. first we break the result set into groups where a group is defined as contigious dates for a given ID. We do this by checking the prior date and seeing if its &lt; the current rows date - 1 with <code>lag(val, 1) over(partition by id order by val)</code></p> <pre><code>SQL&gt; 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) &lt; 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. </code></pre> <p>we need to fill in the blanks next so that the blanks associate the non-null group that preceeded it. i.e. we apply a max() to this with <code>max(grp) over(partition by id order by val)</code> the order by here means that we are only taking the max row seen up to that point and not the max across the whole set. </p> <pre><code>SQL&gt; 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) &lt; 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. </code></pre> <p>now its a simple group by (id, grp) to be applied, taking the min() and max() for each id+group.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload