[英]How to extract values from column of mysql table having partial Json array values and remaining with string values
[英]how to extract json array as table from mysql text column when number of json objects in array is unknown?
有沒有一種方法可以從包含帶有不同數量json對象的json數組的文本列中提取數據到表?
例如,如果我...
CREATE TABLE tableWithJsonStr (location TEXT, jsonStr TEXT);
INSERT INTO tableWithJsonStr VALUES
('Home', '[{"animalId":"1","type":"dog", "color":"white","isPet":"1"},{"animalId":"2","type":"cat", "color":"brown","isPet":"1"}]'),
('Farm', '[{"animalId":"8","type":"cow", "color":"brown","isPet":"0"}, {"animalId":"33","type":"pig", "color":"pink","isPet":"0"}, {"animalId":"22","type":"horse", "color":"black","isPet":"1"}]'),
('Zoo', '[{"animalId":"5","type":"tiger", "color":"stripes","isPet":"0"}]');
和
CREATE TABLE animal (
location TEXT,
idx INT,
animalId INT,
type TEXT,
color TEXT,
isPet BOOLEAN
);
我可以通過運行以下命令提取tableWithJsonStr.jsonStr:
INSERT INTO animal
SELECT location,
idx AS id,
TRIM(BOTH'"' FROM JSON_EXTRACT(jsonStr, CONCAT('$[', idx, '].animalId'))) AS animalId,
TRIM(BOTH'"' FROM JSON_EXTRACT(jsonStr, CONCAT('$[', idx, '].type'))) AS type,
TRIM(BOTH'"' FROM JSON_EXTRACT(jsonStr, CONCAT('$[', idx, '].color'))) AS color,
TRIM(BOTH'"' FROM JSON_EXTRACT(jsonStr, CONCAT('$[', idx, '].isPet'))) AS isPet
FROM tableWithJsonStr
JOIN(
SELECT 0 AS idx UNION
SELECT 1 AS idx UNION
SELECT 2 AS idx UNION
SELECT 3 AS idx
) AS indexes
WHERE JSON_EXTRACT(jsonStr, CONCAT('$[', idx, ']')) IS NOT NULL;
動物表的結果是:
| location | idx | animalId | type | color | isPet |
|==========|=====|==========|=======|=========|=======|
| Farm | 0 | 8 | cow | brown | 0 |
| Farm | 1 | 33 | pig | pink | 0 |
| Farm | 2 | 22 | horse | black | 1 |
| Home | 0 | 1 | dog | white | 1 |
| Home | 1 | 2 | cat | brown | 1 |
| Zoo | 0 | 5 | tiger | stripes | 0 |
盡管該解決方案有效,但它是不可擴展的。 如果我的json數組中有3個以上的對象,除非我在JOIN中添加另一個SELECT 4 AS idx,否則不會考慮它們。 有沒有更好的方法可以遍歷數組中不需要預先知道每個數組中可能存在的最大對象數的對象?
如果您使用的是MySQL 8.0,則可以使用JSON_TABLE
命令從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
輸出:
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
如果您堅持使用MySQL 5.7,則可以使用存儲過程來提取數據:
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 $$
輸出:
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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.