SELECTing min, max (maybe length) of continuous id ranges in a table I have a table foo in Postgres (10.3)

# select * from foo;
 id | cust  |  load_dt
----+-------+------------
  1 | cust1 |
  2 | cust1 |
  3 | cust1 |
  4 | cust2 | 2018-05-15
  5 | cust2 | 2018-05-15
  6 | cust1 |
  7 | cust1 |
  8 | cust3 | 2018-05-17
(8 rows)


from which I've been trying to get the start and end ids for each continuous range of ids:

 min | max | cust  |  load_dt
-----+-----+-------+------------
   1 |   3 | cust1 |
   4 |   5 | cust2 | 2018-05-15
   6 |   7 | cust1 |
   8 |   8 | cust3 | 2018-05-17


but all my tries have ended basically to this:

   1 |   7 | cust1 |
...


Length of each range would be a nice touch.

Test stuff:

create table foo (
  id serial,
  cust text,
  load_dt date
);

insert into foo(cust,load_dt) 
values ('cust1',NULL),('cust1',NULL),('cust1',NULL),
       ('cust2','2018-05-15'::date),('cust2','2018-05-15'::date),
       ('cust1',NULL),('cust1',NULL),
       ('cust3','2018-05-17'::date);
You can apply a GROUPING AND WINDOW solution.

select min(id) as min, 
       max(id) as max,
       cust,
       load_dt,
       grp
from (
      select id, cust, load_dt, 
             sum(rst) over (order by id) as grp
      from
      (
          select id, cust, load_dt,
                 case when coalesce(lag(cust) over (order by id), '') &lt;&gt; cust then 1 end as rst
          from   foo
      ) t
     ) t
group by grp, cust, load_dt
order by 1;


This is the result:



min | max | cust  | load_dt    | grp
--: | --: | :---- | :--------- | --:
  1 |   3 | cust1 | null       |   1
  4 |   5 | cust2 | 2018-05-15 |   2
  6 |   7 | cust1 | null       |   3
  8 |   8 | cust3 | 2018-05-17 |   4



db&lt;>fiddle here