如何根据条件从mysql的JSON数组字段中选择JSON对象

问题描述 投票:0回答:2

我有一个带有JSON字段的表,其中包含JSON对象数组。我需要根据某些条件选择对象。

创建并填写表格:

CREATE TABLE test (
    id INT AUTO_INCREMENT PRIMARY KEY,
    json_list JSON
);

INSERT INTO test(json_list) VALUES
("{""list"": [{""type"": ""color"", ""value"": ""red""}, {""type"": ""shape"", ""value"": ""oval""}, {""type"": ""color"", ""value"": ""green""}]}"),
("{""list"": [{""type"": ""shape"", ""value"": ""rect""}, {""type"": ""color"", ""value"": ""olive""}]}"),
("{""list"": [{""type"": ""color"", ""value"": ""red""}]}")
;

现在我需要从所有行中选择type = color的所有对象。

我想看这个输出:

id  extracted_value
1   {"type": "color", "value": "red"}
1   {"type": "color", "value": "green"}
2   {"type": "color", "value": "olive"}
3   {"type": "color", "value": "red"}

也可以得到这个:

id  color
1   red
1   green
2   olive
3   red

我无法更改数据库或JSON。

我正在使用MySQL 5.7

我当前的解决方案

我的解决方案是通过一些索引集交叉连接表,然后提取JSON数组的所有元素。

我不喜欢它,好像一个数组中的对象计数可能很大,要求所有索引直到最大索引为止。它使查询变慢,因为到达数组末尾时它不会停止JSON值的计算。

SELECT 
    test.id,
    JSON_EXTRACT(test.json_list, CONCAT('$.list[', ind.ind, ']')),
    ind.ind
FROM
    test
CROSS JOIN
    (SELECT 0 AS ind UNION ALL SELECT 1 AS ind UNION ALL SELECT 2 AS ind) ind
WHERE
    JSON_LENGTH(json_list, "$.list") > ind.ind
    AND JSON_EXTRACT(json_list, CONCAT('$.list[', ind.ind, '].type')) = "color";

通过更改JSON_EXTRACT路径很容易只获得值。但这有更好的方法吗?

编辑

  • [添加了对json_list.list长度的检查。在这种情况下,这会过滤掉67%的派生表行。
mysql arrays json mysql-5.7
2个回答
0
投票
SELECT test.id, JSON_EXTRACT(test.json_list, CONCAT('$.list[', ind.ind, ']')), ind.ind FROM test CROSS JOIN (SELECT 0 AS ind UNION ALL SELECT 1 AS ind UNION ALL SELECT 2 AS ind) ind WHERE JSON_LENGTH(json_list, "$.list") > ind.ind AND JSON_EXTRACT(json_list, CONCAT('$.list[', ind.ind, '].type')) = "color";

0
投票
© www.soinside.com 2019 - 2024. All rights reserved.