Reputation: 13500
So I have a table which looks like:
SITE LOWER UPPER SIZE
a.com 0.1 0.2 10
a.com 0.2 0.3 10
a.com 0.3 0.4 10
a.com 0.7 0.8 10
a.com 0.9 1.0 10
b.com 0.1 0.2 20
a.com 0.6 0.7 30
My desired output would be:
SITE LOWER UPPER SIZE
a.com 0.1 0.4 10
a.com 0.7 1.0 10
b.com 0.1 0.2 20
a.com 0.6 0.7 30
So for a SITE
and SIZE
pair, I need to compress LOWER
and UPPER
values where LOWER
of the grouped by row is the minimum of the first row and UPPER
is the maximum of the last row.LOWER
and UPPER
are like lower and upper bound values of some buckets (e.g. [0.1, 0.2]) and I only need consecutive buckets to be compressed together. Any help would be much appreciated in this regard.
Upvotes: 0
Views: 189
Reputation: 1269443
You can assign a group id to the adjacent rows using variables:
select t.*,
(@grp := IF(@sru = CONCAT_WS(':', site, rev, lower),
IF(@sru := CONCAT_WS(':', site, rev, upper), @grp, @grp),
IF(@sru := CONCAT_WS(':', site, rev, upper) , @grp + 1, @grp + 1)
)
) as grp
from (select t.*
from t
order by site, size, lower
) cross join
(select @grp := 0, @sru := '') params;
You can then aggregate to get what you want:
select site, size, min(lower) as lower, max(upper) as upper
from (select t.*,
(@grp := IF(@sru = CONCAT_WS(':', site, rev, lower),
IF(@sru := CONCAT_WS(':', site, rev, upper), @grp, @grp),
IF(@sru := CONCAT_WS(':', site, rev, upper) , @grp + 1, @grp + 1)
)
) as grp
from (select t.*
from t
order by site, size, lower
) cross join
(select @grp := 0, @sru := '') params
) t
group by size, size, grp;
Here is a SQL Fiddle.
Upvotes: 2