Der er ikke meget at ændre i din forespørgsel. Du skal grundlæggende vælge name
og number
i underforespørgslen og sorter i samme rækkefølge. Derefter kan du gruppere efter name, number - rn
i den ydre forespørgsel.
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;
Resultat:
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
Jeg plejer at gå ind for brugen af sessionsvariabler på denne måde. Årsagen er, at sådanne løsninger afhænger af intern implementering og kan brydes af versionsopdateringer eller indstillingsændringer. For eksempel:En gang besluttede MariaDB at ignorere ORDER BY-klausulen i underforespørgsler uden LIMIT. Det er derfor, jeg inkluderede en enorm LIMIT.
Jeg erstattede også number
med first_number
i den ydre ORDER BY-klausul for at undgå problemer med ONLY_FULL_GROUP_BY-tilstand.
En mere stabil måde at generere rækkenumre på er at bruge en AOTO_INCREMENT kolonne i en midlertidig tabel:
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;
Den endelige SELECT-forespørgsel er identisk med den ydre forespørgsel ovenfor:
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;
I en nyere version (startende fra MariaDB 10.2) kan du bruge ROW_NUMBER()
vinduesfunktion i stedet:
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;