简体   繁体   中英

Aggregate rows based on ordered columns in SQL

I have a table with ordered columns by name, from:

Name   from   to   code
name1   0      1    cal
name1   1      2    cal/top
name1   2      4    cal
name1   4      5    top
name1   5      6    cal
name2   0      3    top
name2   3      5    cal
name2   5      7    cal/top

where I want to aggregate them into a table based on code like CAL :

Name    minFrom   MaxTo  
name1    0         4
name1    5         6
name2    3         7

I have tried this:

SELECT name, MIN(from) AS minfrom, MAX(to) AS maxto
FROM table1
GROUP BY name, code, From
HAVING code like "*CAL*"
ORDER BY name,  From;

and searched for a like question on stackoverflow with no luck. I think I'll have to do a select subquery but I have no idea where to start... Please help! BTW I'm using postgresql...

You can identify the groups of similar records by using a difference of row numbers. This gives you a grouping column, which can then be used for aggregation:

select name, min(from) as minfrom, max(to) as maxto
from (select t.*,
             (row_number() over (partition by name order by from) -
              row_number() over (partition by name,
                                              (case when code like 'col%' then 1 else 0 end)
                                 order by from
                                )
             ) as grp
      from table1 t
     ) t
where code not like 'col%' 
group by grp, name;

Have you been able to reproduce without the need for a partition table? I think just dropping your having statement may make sense for a where statement.

SELECT name, MIN(from) AS minfrom, MAX(to) AS maxto
FROM table1
Where code like "*CAL*"
GROUP BY name, code, From
ORDER BY name,  From;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM