Search code examples
postgresqlmaxstring-aggregationstring-agg

postgres I was given a set of number like "1,2,3,6,7,8,11,12,15,18,19,20" obtain maximum of each group consecutive numbers


the consecutive numbers are grouped by the query below, but I dont know how to obtain the maximum of each group of consecutive numbers

with trans as (
  select c1, 
         case when lag(c1) over (order by c1) = c1 - 1 then 0 else 1 end as new
    from table1
), groups as (
  select c1, sum(new) over (order by c1) as grpnum
    from trans
), ranges as (
  select grpnum, min(c1) as low, max(c1) as high
    from groups
   group by grpnum
), texts as (
  select grpnum, 
         case 
           when low = high then low::text 
           else low::text||'-'||high::text
         end as txt
    from ranges
)
select string_agg(txt, ',' order by grpnum) as number
  from texts;

Solution

  • In R, we can create a group with diff and cumsum, and then use tapply to get the max of the vector for each group

    grp <- cumsum(c(TRUE, diff(v1) > 1))
    tapply(v1, grp, FUN = max)
    #   1  2  3  4  5 
    #   3  8 12 15 20 
    

    data

    v1 <- c(1, 2, 3, 6, 7, 8, 11, 12, 15, 18, 19, 20)