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

Konverter JSON-array i MySQL til rækker

Det er rigtigt, at det ikke er en god idé at denormalisere til JSON, men nogle gange har du brug for at håndtere JSON-data, og der er en måde at udtrække et JSON-array i rækker i en forespørgsel.

Tricket er at udføre en join på en midlertidig eller inline tabel af indekser, som giver dig en række for hver ikke-null værdi i et JSON array. Dvs., hvis du har en tabel med værdierne 0, 1 og 2, som du forbinder med et JSON-array "fish" med to poster, så matcher fish[0] 0, hvilket resulterer i én række, og fish1 matcher 1, hvilket resulterer i en anden række, men fish[2] er null, så den matcher ikke de 2 og producerer ikke en række i sammenføjningen. Du skal bruge lige så mange tal i indekstabellen som den maksimale længde af ethvert array i dine JSON-data. Det er lidt af et hack, og det er omtrent lige så smertefuldt som OP's eksempel, men det er meget praktisk.

Eksempel (kræver MySQL 5.7.8 eller nyere):

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 er:

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

Det ser ud til, at MySQL-teamet kan tilføje en JSON_TABLE funktion i MySQL 8 for at gøre alt dette nemmere. (http://mysqlserverteam.com/mysql-8-0 -labs-json-aggregation-functions/ ) (MySQL-teamet har tilføjede en JSON_TABLE funktion.)



  1. Hvor er bordet, der holder specialprisen i Magento?

  2. PostgreSQL GROUP_CONCAT() ækvivalent

  3. Hvordan justify_days() virker i PostgreSQL

  4. Hvordan skal jeg tackle --secure-file-priv i MySQL?