Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Wie könnte Untergruppen eine generierte Inkrementspalte in einer SQL-Abfrage hinzugefügt werden?

Ich habe es gelöst, dank der Hilfe eines hervorragenden Blog-Beitrags hier:http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/

Die Lösung ist nicht trivial und erfordert Variablen und einige fortgeschrittene Kenntnisse darüber, wie mysql seine Abfrageoperationen anordnet, aber sie scheint ziemlich leistungsfähig zu sein. Einer der Schlüssel ist, dass Variablenzuweisungen innerhalb von Funktionsaufrufen versteckt werden können!

Im Wesentlichen löst die folgende Abfrage das Problem:

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

Die Funktionen GREATEST , LEAST , und LENGTH sind nur als Container für Variablenzuweisungen da. Wie Sie sehen können, wirken sich diese Funktionen im Wesentlichen nicht auf die Ausgabe der Abfrage aus.

Ich habe jedoch auch festgestellt, dass ich in meiner Tabelle „Untergruppen“-Werte hatte, die nicht aufeinander folgten. Zum Beispiel:

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

Ergebnis war eine Ausgabetabelle wie diese:

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

Anheften eines ORDER BY -Klausel am Ende der Abfrage funktionierte aufgrund der Ausführungsreihenfolge nicht und das Ausblenden der Variablenzuweisungen in ORDER BY -Klausel kam näher, hatte aber ihre eigenen Probleme, also ist hier die letzte Abfrage, die ich verwendet habe:

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

Daraus ergibt sich die folgende Ausgabe:

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

Juhu!