To prawda, że denormalizacja do formatu JSON nie jest dobrym pomysłem, ale czasami trzeba mieć do czynienia z danymi JSON, a istnieje sposób na wyodrębnienie tablicy JSON do wierszy w zapytaniu.
Sztuczka polega na wykonaniu sprzężenia na tymczasowej lub wbudowanej tabeli indeksów, co daje wiersz dla każdej wartości innej niż null w tablicy JSON. Np. jeśli masz tabelę z wartościami 0, 1 i 2, którą łączysz z tablicą JSON „fish” z dwoma wpisami, wtedy fish[0] odpowiada 0, co daje jeden wiersz, a fish1 dopasowuje 1, co daje drugi wiersz, ale fish[2] ma wartość null, więc nie pasuje do 2 i nie tworzy wiersza w łączeniu. Potrzebujesz tylu liczb w tabeli indeksów, ile wynosi maksymalna długość dowolnej tablicy w danych JSON. To trochę hack i jest mniej więcej tak bolesny jak przykład OP, ale jest bardzo przydatny.
Przykład (wymaga MySQL 5.7.8 lub nowszego):
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;
Wynik:
+---------+-----+---------+
| rec_num | idx | fishes |
+---------+-----+---------+
| 1 | 0 | "red" |
| 1 | 1 | "blue" |
| 2 | 0 | "one" |
| 2 | 1 | "two" |
| 2 | 2 | "three" |
+---------+-----+---------+
Wygląda na to, że zespół MySQL może dodać (Zespół MySQL ma dodano JSON_TABLE
funkcja w MySQL 8, aby to wszystko ułatwić. (http://mysqlserverteam.com/mysql-8-0 -labs-json-agregation-functions/
)JSON_TABLE
funkcja.)