Se estiver usando o MySQL 8.0, você pode usar o
JSON_TABLE
comando para extrair seus dados de cada linha de JSON
:SELECT t1.location, farm.*
FROM tableWithJsonStr t1
JOIN JSON_TABLE(t1.jsonStr,
'$[*]'
COLUMNS (idx FOR ORDINALITY,
animalId INT PATH '$.animalId',
type TEXT PATH '$.type',
color TEXT PATH '$.color',
isPet BOOLEAN PATH '$.isPet')
) farm
ORDER BY location, idx
Resultado:
location idx animalId type color isPet
Farm 1 8 cow brown 0
Farm 2 33 pig pink 0
Farm 3 22 horse black 1
Home 1 1 dog white 1
Home 2 2 cat brown 1
Zoo 1 5 tiger stripes 0
Demonstração no dbfiddle
Se você está preso ao MySQL 5.7, você pode usar um procedimento armazenado para extrair os dados:
DELIMITER $$
CREATE PROCEDURE extract_animals()
BEGIN
DECLARE idx INT;
DECLARE finished INT DEFAULT 0;
DECLARE location, json VARCHAR(200);
DECLARE json_cursor CURSOR FOR SELECT location, jsonStr FROM tableWithJsonStr;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
DROP TABLE IF EXISTS animal;
CREATE TABLE animal (location TEXT, idx INT, animalId INT, type TEXT, color TEXT, isPet BOOLEAN);
OPEN json_cursor;
json_loop: LOOP
FETCH json_cursor INTO location, json;
IF finished = 1 THEN
LEAVE json_loop;
END IF;
SET idx = 0
WHILE JSON_CONTAINS_PATH(json, 'one', CONCAT('$[', idx, ']))
INSERT INTO animal VALUES(location,
idx,
JSON_UNQUOTE(JSON_EXTRACT(jsonStr, CONCAT('$[', idx, '].animalId'))),
JSON_UNQUOTE(JSON_EXTRACT(jsonStr, CONCAT('$[', idx, '].type'))),
JSON_UNQUOTE(JSON_EXTRACT(jsonStr, CONCAT('$[', idx, '].color'))),
JSON_UNQUOTE(JSON_EXTRACT(jsonStr, CONCAT('$[', idx, '].isPet')));
SET idx = idx + 1;
END WHILE;
END LOOP json_loop;
END $$
Resultado:
location idx animalId type color isPet
Home 0 1 dog white 1
Home 1 2 cat brown 1
Farm 0 8 cow brown 0
Farm 1 33 pig pink 0
Farm 2 22 horse black 1
Zoo 0 5 tiger stripes 0
Demonstração no dbfiddle