sql >> Database >  >> RDS >> Mysql

Hoe kunnen subgroepen een gegenereerde incrementkolom hebben toegevoegd aan een sql-query?

Ik heb het opgelost, dankzij de hulp van een uitstekende blogpost hier:http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/

De oplossing is niet triviaal en vereist variabelen en enige geavanceerde kennis van hoe mysql zijn query-operaties ordent, maar het lijkt redelijk goed te presteren. Een van de sleutels is dat variabele toewijzingen kunnen worden verborgen binnen functieaanroepen!

In wezen lost de volgende vraag het probleem op:

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

De functies GREATEST , LEAST , en LENGTH zijn er gewoon als containers voor variabele opdrachten. Zoals u kunt zien, doen deze functies in wezen niets om de uitvoer van de query te beïnvloeden.

Ik ontdekte echter ook dat ik "subgroep" -waarden in mijn tabel had die niet opeenvolgend waren. Bijvoorbeeld:

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

Resulteerde in een uitvoertabel als volgt:

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

Een ORDER BY tackelen clausule aan het einde van de query werkte niet vanwege de uitvoeringsvolgorde en het verbergen van de variabeletoewijzingen in de ORDER BY clausule kwam dichterbij maar had zijn eigen problemen, dus hier is de laatste vraag die ik heb gebruikt:

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

Resulterend in de volgende 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 |
+------+----------+-----------+

Yay!



  1. Twee query's mysql in één object json

  2. Fix 'ERROR:kolom "colname" bestaat niet' in PostgreSQL bij gebruik van UNION, BEHALVE of INTERSECT

  3. Is het mogelijk om een ​​apriori-associatieregel in de mysql-instructie uit te voeren?

  4. Maak een tijdelijke tabel in een SELECT-instructie zonder een aparte CREATE TABLE