Вярно е, че не е добра идея да денормализирате в JSON, но понякога трябва да се справите с JSON данни и има начин да извлечете JSON масив в редове в заявка.
Номерът е да извършите присъединяване към временна или вградена таблица с индекси, която ви дава ред за всяка ненулева стойност в JSON масив. Т.е., ако имате таблица със стойности 0, 1 и 2, която присъединявате към JSON масив „fish“ с два записа, тогава fish[0] съвпада с 0, което води до един ред, а fish1 съвпада с 1, което води до втори ред, но fish[2] е нула, така че не съвпада с 2 и не създава ред в съединението. Нуждаете се от толкова числа в индексната таблица, колкото е максималната дължина на който и да е масив във вашите JSON данни. Това е малко хак и е толкова болезнено, колкото и примера с ОП, но е много удобен.
Пример (изисква 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
функция в MySQL 8, за да направи всичко това по-лесно. (http://mysqlserverteam.com/mysql-8-0 -labs-json-aggregation-functions/
)JSON_TABLE
функция.)