sql >> Databasteknik >  >> RDS >> Mysql

Konvertera JSON-array i MySQL till rader

Det är sant att det inte är en bra idé att avnormalisera till JSON, men ibland måste du hantera JSON-data, och det finns ett sätt att extrahera en JSON-array i rader i en fråga.

Tricket är att utföra en join på en temporär eller inline-tabell med index, vilket ger dig en rad för varje icke-nullvärde i en JSON-array. Dvs om du har en tabell med värdena 0, 1 och 2 som du kopplar till en JSON-array "fish" med två poster, matchar fish[0] 0, vilket resulterar i en rad, och fish1 matchar 1, vilket resulterar i en andra rad, men fish[2] är null så den matchar inte 2:an och ger inte en rad i sammanfogningen. Du behöver lika många siffror i indextabellen som maxlängden för en array i din JSON-data. Det är lite av ett hack, och det är ungefär lika smärtsamt som OP:s exempel, men det är väldigt praktiskt.

Exempel (kräver MySQL 5.7.8 eller senare):

CREATE TABLE t1 (rec_num INT, jdoc JSON);
INSERT INTO t1 VALUES 
  (1, '{"fish": ["red", "blue"]}'), 
  (2, '{"fish": ["one", "two", "three"]}');

SELECT
  rec_num,
  idx,
  JSON_EXTRACT(jdoc, CONCAT('$.fish[', idx, ']')) AS fishes
FROM t1
  -- Inline table of sequential values to index into JSON array
JOIN ( 
  SELECT  0 AS idx UNION
  SELECT  1 AS idx UNION
  SELECT  2 AS idx UNION
  -- ... continue as needed to max length of JSON array
  SELECT  3
  ) AS indexes
WHERE JSON_EXTRACT(jdoc, CONCAT('$.fish[', idx, ']')) IS NOT NULL
ORDER BY rec_num, idx;

Resultatet är:

+---------+-----+---------+
| rec_num | idx | fishes  |
+---------+-----+---------+
|       1 |   0 | "red"   |
|       1 |   1 | "blue"  |
|       2 |   0 | "one"   |
|       2 |   1 | "two"   |
|       2 |   2 | "three" |
+---------+-----+---------+

Det verkar som att MySQL-teamet kan lägga till en JSON_TABLE funktion i MySQL 8 för att göra allt detta enklare. (http://mysqlserverteam.com/mysql-8-0 -labs-json-aggregation-functions/ ) (MySQL-teamet har lade till en JSON_TABLE funktion.)



  1. Konvertera MySQL-skript till H2

  2. Beräknade / beräknade / virtuella / härledda kolumner i PostgreSQL

  3. MySQL:Lägg till sekvenskolumn baserat på ett annat fält

  4. SQLite CHECK-begränsningar