Reputation: 974
say I have the following data:
id value
uid1 20
uid1 23
uid1 30
uid1 31
uid1 32
uid1 37
uid1 39
uid1 45
uid2 33
uid2 34
I want to group it so:
id value
uid1 20,23
uid1 30,31,32,37,39
uid1 45
uid2 33,34
the logic is:
group records with 'consecutive' values.
by consecutive I mean val1-val2 <= 5
5 is just an example I would like to solve it for any threshold I decide...
in the example 30 & 39 are in the same group because they are part of a chain of numbers that differ in no more than 5.
Is there any way to achieve it in MySQL?
Thanks
Upvotes: 0
Views: 54
Reputation: 520898
Gordon's query seems to be working, but I would offer an alternative using session variables. We can iterate over your table and check at each step whether a gap of 5 difference in the value occurs. If it does, we form a new group, and we also reset the gaps when the id
changes.
This may seem like overkill, but if the criteria for forming gaps and islands were more complex, then this approach might be more useful.
SET @gn = 0;
SET @id = NULL;
SET @value = NULL;
SET @threshold = 5; -- or whatever value you want here
SELECT
t.id,
GROUP_CONCAT(t.value ORDER BY t.value) AS value
FROM
(
SELECT @gn:=CASE WHEN @id <> id THEN 0
WHEN value - @value > @threshold THEN @gn + 1
ELSE @gn END AS gn,
@value:=value AS value,
@id:=id AS id
FROM yourTable
ORDER BY id, value
) t
GROUP BY t.id, t.gn;
Output:
Demo here:
Upvotes: 1
Reputation: 1269463
It seems like some simple arithmetic will do:
select id, group_concat(value order by value) as values
from t
group by id, floor(value / 10);
Or, if value
is a string:
select id, group_concat(value order by value) as values
from t
group by id, left(value, 1);
Upvotes: 1