sql >> Databasteknik >  >> RDS >> Mysql

Hur kan undergrupper ha en genererad inkrementkolumn tillagd i en sql-fråga?

Jag har löst det, tack vare hjälp från ett mycket utmärkt blogginlägg här:http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/

Lösningen är icke-trivial, kräver variabler och en del avancerad kunskap om hur mysql ordnar sina frågeoperationer, men den verkar vara ganska presterande. En av nycklarna är att variabeltilldelningar kan döljas i funktionsanrop!

I huvudsak löser följande fråga problemet:

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

Funktionerna GREATEST , LEAST och LENGTH finns bara där som behållare för variabla uppdrag. Som du kan se gör dessa funktioner i princip ingenting för att påverka resultatet av frågan.

Men jag upptäckte också att jag hade "undergrupp"-värden i min tabell som inte var konsekutiva. Till exempel:

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

Resulterade i en utdatatabell så här:

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

Skickar en ORDER BY satsen i slutet av frågan fungerade inte på grund av exekveringsordern och gömda variabeltilldelningarna i ORDER BY klausulen kom närmare men hade sina egna problem, så här är den sista frågan som jag använde:

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

Resulterar i följande utdata:

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

Jaja!



  1. Resque Mysql2::Error:Användaren har överskridit resursen 'max_user_connections' (aktuellt värde:10)

  2. 2 sätt att se om föråldrade funktioner fortfarande används i en SQL Server-instans

  3. REGEX för att välja n:te värde från en lista, vilket tillåter nollvärden

  4. Räknar antalet matchade ord