======[MySQL] Serien gruppieren====== In einem Feld (in einem Beispiel id) sind Serien gespeichert. Alle aufeinander folgenden Nummern gelten als Serie. ===== Ausgangslage ===== CREATE TABLE test (`id` int) ; INSERT INTO test (`id`) VALUES (1), (3), (4), (5), (7), (8), (10) ; Das ganze soll dann so ausgegeben werden: 1 3-5 7-8 10 ===== Code neu ===== Heute kahm mir eine elgantere Lösung in den Sinn. Ich geh davon aus, dass sie auch schneller ist, da sie ohne Subselect im SELECT Teil auskommt. Die Logik ist umgedreht. statt vorwärts wird jetzt Rückwärts geschaut. SELECT CASE WHEN MIN(prep.id) = MAX(prep.id) THEN MIN(prep.id) ELSE CONCAT(MIN(prep.id), '-', MAX(prep.id)) END AS id_range FROM ( SELECT @range_id := @range_id + IF(@last_id + 1 = t.id, 0, 1) AS range_id, @last_id := t.id AS id FROM -- Variablen deklarieren (SELECT @last_id := 0, @range_id:= 0) AS vars, (SELECT * FROM test ORDER BY id) AS t ) AS prep GROUP BY prep.range_id ===== Code alt ===== Und hier mein Lösungsansatz SELECT CASE WHEN MIN(prep.id) = MAX(prep.id) THEN MIN(prep.id) ELSE CONCAT(MIN(prep.id), '-', MAX(prep.id)) END AS id_range FROM ( SELECT -- Letzte Gruppe als GruppenId nehmen @group_id AS group_id, t.id, -- Nächte Gruppe ermitteln @group_id := CASE WHEN (t.id+1) NOT IN (SELECT id FROM test) THEN @group_id + 1 -- Die nexte ID exisitert nicht, ergo Gruppen-ID um eins erhöhen ELSE @group_id -- Due Gruppen-ID bleibt unverändert END AS next_group_id FROM (SELECT @group_id := 1) vars, test t ) prep GROUP BY prep.group_id; ===== Spielwiese ===== *[[http://sqlfiddle.com/#!2/4d6ab2/1|Neues Beispiel bei sqlfiddle.com]] *[[http://sqlfiddle.com/#!2/76b15/23|Altes Beispiel bei sqlfiddle.com]] {{tag>MySQL}}