Er verandert niet veel aan uw zoekopdracht. U moet in principe name
selecteren en number
in de subquery en sorteer in dezelfde volgorde. Dan kun je groeperen op name, number - rn
in de buitenste vraag.
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;
Resultaat:
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
Ik pleit meestal tegen het gebruik van sessievariabelen op deze manier. De reden is dat dergelijke oplossingen afhankelijk zijn van interne implementatie en kunnen worden verbroken door versie-updates of instellingenwijzigingen. Bijvoorbeeld:zodra MariaDB besloot om de ORDER BY-clausule in subquery's zonder LIMIT te negeren. Daarom heb ik een enorme LIMIET opgenomen.
Ik heb ook number
vervangen met first_number
in de buitenste ORDER BY-clausule om problemen met de ONLY_FULL_GROUP_BY-modus te voorkomen.
Een stabielere manier om rijnummers te genereren, is door een AOTO_INCREMENT-kolom in een tijdelijke tabel te gebruiken:
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;
De laatste SELECT-query is identiek aan de buitenste query hierboven:
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 een recentere versie (vanaf MariaDB 10.2) kunt u ROW_NUMBER()
gebruiken vensterfunctie in plaats daarvan:
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;