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