An deiner Abfrage ist nicht viel zu ändern. Sie müssen grundsätzlich name
auswählen und number
in der Unterabfrage und sortieren in der gleichen Reihenfolge. Dann können Sie nach name, number - rn
gruppieren in der äußeren Abfrage.
SELECT
min(number) first_number,
max(number) last_number,
count(*) AS no_records,
name
FROM (
SELECT c.*, @rn := @rn + 1 rn
from (
SELECT name, number
FROM `table`
WHERE cc = 1
ORDER BY name, number
LIMIT 99999999999999999
) AS c
CROSS JOIN (SELECT @rn := 0) r
) c
GROUP BY name, number - rn
ORDER BY first_number ASC, name ASC;
Ergebnis:
first_number last_number no_records name
1 2 2 Apple
3 3 1 Bean
10 12 3 Hello
14 14 1 Deer
14 14 1 Door
15 15 1 Hello
17 17 1 Hello
Normalerweise plädiere ich gegen die Verwendung von Session-Variablen auf diese Weise. Der Grund dafür ist, dass solche Lösungen von der internen Implementierung abhängen und durch Versionsaktualisierungen oder Einstellungsänderungen beschädigt werden können. Zum Beispiel:Einmal entschied sich MariaDB, die ORDER BY-Klausel in Unterabfragen ohne LIMIT zu ignorieren. Aus diesem Grund habe ich ein riesiges LIMIT eingefügt.
Ich habe auch number
ersetzt mit first_number
in der äußeren ORDER BY-Klausel, um Probleme mit dem ONLY_FULL_GROUP_BY-Modus zu vermeiden.
Eine stabilere Methode zum Generieren von Zeilennummern ist die Verwendung einer AOTO_INCREMENT-Spalte in einer temporären Tabelle:
drop temporary table if exists tmp_tbl;
create temporary table tmp_tbl (
rn int unsigned auto_increment primary key,
name varchar(64) not null,
number int not null
);
insert into tmp_tbl (name, number)
select name, number
from `table`
order by name, number;
Die abschließende SELECT-Abfrage ist identisch mit der äußeren Abfrage oben:
SELECT
min(number) first_number,
max(number) last_number,
count(*) AS no_records,
name
FROM tmp_tbl
GROUP BY name, number - rn
ORDER BY first_number ASC, name ASC;
In einer neueren Version (ab MariaDB 10.2) können Sie ROW_NUMBER()
verwenden Fensterfunktion statt:
SELECT
min(number) first_number,
max(number) last_number,
count(*) AS no_records,
name
FROM (
SELECT
name,
number,
row_number() OVER (ORDER BY name, number) as rn
FROM `table`
WHERE cc = 1
) c
GROUP BY name, number - rn
ORDER BY first_number ASC, name ASC;