No hay mucho que cambiar en su consulta. Básicamente necesitas seleccionar name
y number
en la subconsulta y ordenar en el mismo orden. Luego puede agrupar por name, number - rn
en la consulta externa.
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;
Resultado:
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
Por lo general, defiendo el uso de variables de sesión de esta manera. La razón es que tales soluciones dependen de la implementación interna y pueden romperse por actualizaciones de versión o cambios de configuración. Por ejemplo:Una vez que MariaDB decidió ignorar la cláusula ORDER BY en subconsultas sin LIMIT. Es por eso que incluí un LÍMITE enorme.
También reemplacé number
con first_number
en la cláusula ORDER BY externa para evitar problemas con el modo ONLY_FULL_GROUP_BY.
Una forma más estable de generar números de fila es usar una columna AOTO_INCREMENT en una tabla temporal:
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;
La consulta SELECT final es idéntica a la consulta externa anterior:
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;
En una versión más reciente (a partir de MariaDB 10.2) puede usar ROW_NUMBER()
función de ventana en su lugar:
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;