sql >> Base de Datos >  >> RDS >> Mysql

¿Cómo podrían los subgrupos tener una columna de incremento generada agregada en una consulta sql?

Lo he resuelto, gracias a la ayuda de una excelente publicación de blog aquí:http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/

La solución no es trivial, requiere variables y un conocimiento avanzado de cómo mysql ordena sus operaciones de consulta, pero parece ser bastante eficiente. ¡Una de las claves es que las asignaciones de variables se pueden ocultar dentro de las llamadas a funciones!

Esencialmente, la siguiente consulta resuelve el problema:

SET @num := 0, @type := '';

SELECT name, subgroup, @num AS increment
FROM table_name
WHERE 0 <= GREATEST(
   @num := IF(@type = subgroup, @num + 1, 1),
   LEAST(0, LENGTH(@type := subgroup)))

Las funciones GREATEST , LEAST y LENGTH simplemente están ahí como contenedores para asignaciones de variables. Como puede ver, esas funciones esencialmente no hacen nada para afectar el resultado de la consulta.

Sin embargo, también descubrí que tenía valores de "subgrupo" en mi tabla que no eran consecutivos. Por ejemplo:

+------+----------+
| name | subgroup |
+------+----------+
| john | 1        |
| doe  | 1        |
| jim  | 1        |
| greg | 2        |
| boe  | 2        |
| amos | 3        |
| ben  | 1        |
| gary | 2        |
+------+----------+

Resultó en una tabla de salida como esta:

+------+----------+-----------+
| name | subgroup | increment |
+------+----------+-----------+
| john | 1        |         1 |
| doe  | 1        |         2 |
| jim  | 1        |         3 |
| greg | 2        |         1 |
| boe  | 2        |         2 |
| amos | 3        |         1 |
| ben  | 1        |         1 |
| gary | 2        |         1 |
+------+----------+-----------+

Agregando un ORDER BY La cláusula al final de la consulta no funcionó debido al orden de ejecución y al ocultar las asignaciones de variables en ORDER BY La cláusula se acercó pero tenía sus propios problemas, así que aquí está la consulta final que usé:

SET @num := 0, @type := '';

SELECT name, subgroup, @num AS increment
FROM (SELECT * FROM table_name ORDER BY subgroup) AS table_name2
WHERE 0 <= GREATEST(
   @num := IF(@type = subgroup, @num + 1, 1),
   LEAST(0, LENGTH(@type := subgroup)))

Dando como resultado el siguiente resultado:

+------+----------+-----------+
| name | subgroup | increment |
+------+----------+-----------+
| john | 1        |         1 |
| doe  | 1        |         2 |
| jim  | 1        |         3 |
| ben  | 1        |         4 |
| greg | 2        |         1 |
| boe  | 2        |         2 |
| gary | 2        |         3 |
| amos | 3        |         1 |
+------+----------+-----------+

¡Hurra!