sql >> データベース >  >> RDS >> Mysql

MySQLのJSON配列を行に変換する

    確かに、JSONに非正規化するのは良い考えではありませんが、JSONデータを処理する必要がある場合があり、JSON配列をクエリの行に抽出する方法があります。

    秘訣は、インデックスの一時テーブルまたはインラインテーブルで結合を実行することです。これにより、JSON配列内のnull以外の値ごとに1つの行が提供されます。つまり、値が0、1、2のテーブルがあり、2つのエントリを持つJSON配列「fish」に結合すると、fish [0]は0に一致し、1つの行になり、fish 1 1に一致すると、2番目の行になりますが、fish [2]はnullであるため、2に一致せず、結合で行を生成しません。インデックステーブルには、JSONデータ内の配列の最大長と同じ数の数値が必要です。これはちょっとしたハックで、OPの例と同じくらい苦痛ですが、非常に便利です。

    例(MySQL 5.7.8以降が必要):

    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;
    

    結果は次のとおりです。

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

    MySQLチームがJSON_TABLEを追加する可能性があるようです これをすべて簡単にするためにMySQL8で機能します。 ( http://mysqlserverteam.com/mysql-8-0 -labs-json-aggregation-functions / (MySQLチームは持っています JSON_TABLEを追加しました 機能。)



    1. PLSQLカーソルの例-明示カーソル、暗黙カーソル、および参照カーソル

    2. MySQL8.0.11エラーcaching_sha2_passwordへの接続指定されたモジュールが見つかりませんでした

    3. ダウンタイムなしでDjangoでインデックスを作成する方法

    4. SQLServer2017でデータベースを作成する