Mysql
 sql >> Database >  >> RDS >> Mysql

In che modo i sottogruppi potrebbero avere una colonna di incremento generata aggiunta in una query sql?

L'ho risolto, grazie all'aiuto di un eccellente post sul blog qui:http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/

La soluzione non è banale, richiede variabili e alcune conoscenze avanzate su come mysql ordina le sue operazioni di query, ma sembra essere abbastanza performante. Una delle chiavi è che le assegnazioni delle variabili possono essere nascoste all'interno delle chiamate di funzione!

In sostanza, la seguente query risolve il 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)))

Le funzioni GREATEST , LEAST e LENGTH sono lì solo come contenitori per assegnazioni variabili. Come puoi vedere, queste funzioni essenzialmente non stanno facendo nulla per influenzare l'output della query.

Tuttavia, ho anche scoperto di avere valori di "sottogruppo" nella mia tabella che non erano consecutivi. Ad esempio:

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

Risultato in una tabella di output in questo modo:

+------+----------+-----------+
| 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 |
+------+----------+-----------+

Affrontare un ORDER BY La clausola alla fine della query non funzionava a causa dell'ordine di esecuzione e nascondeva le assegnazioni delle variabili nel ORDER BY la clausola si è avvicinata ma ha avuto i suoi problemi, quindi ecco la query finale che ho usato:

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)))

Risultato nel seguente output:

+------+----------+-----------+
| 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 |
+------+----------+-----------+

Sì!