Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Group by values that are in sequence

Tags:

sql

oracle

I have some table like this

row chequeNo
 1     15
 2     19
 3     20
 4     35
 5     16

and I need to get the result like this

row  from   to    
 1    15    16     
 2    19    20    
 3    35    35

so I need groups of chequeNo where values would be sequential without any interruptions. chequeNo is unique column. Additionally it should be done with one sql select query, because I haven't permissions to create any sql structures except select queries.

So is it possible?

Would be grateful for any help

like image 428
Harrison Avatar asked Apr 02 '12 13:04

Harrison


2 Answers

You can use Aketi Jyuuzou's technique called Tabibitosan here:

SQL> create table mytable (id,chequeno)
  2  as
  3  select 1, 15 from dual union all
  4  select 2, 19 from dual union all
  5  select 3, 20 from dual union all
  6  select 4, 35 from dual union all
  7  select 5, 16 from dual
  8  /

Table created.

SQL> with tabibitosan as
  2  ( select chequeno
  3         , chequeno - row_number() over (order by chequeno) grp
  4      from mytable
  5  )
  6  select row_number() over (order by grp) "row"
  7       , min(chequeno) "from"
  8       , max(chequeno) "to"
  9    from tabibitosan
 10   group by grp
 11  /

       row       from         to
---------- ---------- ----------
         1         15         16
         2         19         20
         3         35         35

3 rows selected.

Regards,
Rob.

like image 127
Rob van Wijk Avatar answered Sep 27 '22 21:09

Rob van Wijk


This should work with Oracle 10 (only tested with Oracle 11)

select group_nr + 1,
       min(chequeno) as start_value,
       max(chequeno) as end_value
from (
  select chequeno,
         sum(group_change_flag) over (order by rn) as group_nr
  from (
    select row_number() over (order by chequeno) as rn,
           chequeno, 
           case 
             when chequeno - lag(chequeno,1,chequeno) over (order by chequeno) <= 1 then 0 
             else 1
           end as group_change_flag
    from foo
  ) t1
) t2
group by group_nr
order by group_nr

(it should work with any DBMS supporting standard SQL windowing functions, e.g. PostgreSQL, DB2, SQL Server 2012)

like image 42
a_horse_with_no_name Avatar answered Sep 27 '22 21:09

a_horse_with_no_name