misma lógica que rexem, pero funciona en cualquier RDBMS de ventanas con capacidad (no funciona en MySQL todavía):
CREATE TABLE tbl
(
id INT,
val VARCHAR(1)
);
INSERT INTO tbl(id,val)
VALUES(1,'a'),(2,'a'),(3,'a'),(4,'a'),(5,'b'),(6,'b'),(7,'a'),(8,'a'),(9,'a');
fuente:
1 a
2 a
3 a
4 a
5 b
6 b
7 a
8 a
9 a
consulta al estilo de ventanas: (funciona en ventanas-c RDBMS apable):
WITH grouped_result AS
(
SELECT x.id, x.val,
COUNT(CASE WHEN y.val IS NULL OR y.val <> x.val THEN 1 END)
OVER (ORDER BY x.id) AS grp
FROM tbl x LEFT JOIN tbl y ON y.id + 1 = x.id
)
SELECT MIN(id) mi, val, COUNT(*)
FROM grouped_result
GROUP BY val, grp
ORDER BY mi
Salida:
1 a 4
5 b 2
7 a 3
Por cierto, esto es el resultado de la grouped_result sin GROUP BY:
1 a 1
2 a 1
3 a 1
4 a 1
5 b 2
6 b 2
7 a 3
8 a 3
9 a 3
Se siente bien volver a escribir mysqlism-consulta a ANSI -conformando uno :-) Por ahora, mientras que mysql todavía no tiene capacidad para ventanas, la respuesta de rexem es la mejor. Rexem, esa es una buena técnica de mysql (JOIN (SELECCIONAR @rownum: = 0)) allí, y afaik MSSQL y PostgreSQL no admiten variables declaradas implícitamente, ¡felicitaciones! :-)
transpone +1 al lado derecho, luego haga que sea -1. por lo que no producirá escaneo de tabla. mysql no puede tener índice en la expresión –
¡Eso es todo! ¡Muchas gracias! – Kuyenda
Si usa 'CASE WHEN xt.id IS NULL O xt.val! = X.val', el SQL no se romperá cuando val sea intencionalmente NULL, pero aún así captura la primera comparación de desplazamiento. – Kuyenda