MySQL根据属性值返回JSON数组索引

时间:2019-05-17 20:53:24

标签: mysql json

我有一个包含JSON数据的表,如下所示:

{"a": [{"color": "blue", "value": 15}, {"color": "red", "value": 30}]}

我需要获取位于“ blue”同一对象内的“ value”。

我想使用下面的代码:

SELECT JSON_EXTRACT(my_data, '$.a[0].value');

问题在于“蓝色”对象可以位于数组的任何索引中。

那么,有没有一种方法可以先检索索引,然后再使用正确的索引进行查询?

更新

Barmar的答案有效,但是需要用JSON_UNQUOTE()包装

2 个答案:

答案 0 :(得分:1)

使用int getHeight(TreeNode root) { if (root == null) return -1; // Base case return Math.max(getHeight(root.left), getHeight(root.right)) + 1; } boolean isBalanced(TreeNode root) { if (root == null) return true; // Base case int heightDiff = getHeight(root.left) - getHeight(root.right); if (Math.abs(heightDiff) > 1) { return false; } else { // Recurse return isBalanced(root.left) && isBalanced(root.right); } } 查找到JSON_SEARCH()的路径。

blue

SELECT JSON_EXTRACT(my_data, REPLACE(JSON_SEARCH(my_data, 'one', 'blue'), '.color', '.value')) 将返回类似JSON_SEARCH的字符串。 $.a[0].color将其更改为REPLACE,然后提取该元素。

答案 1 :(得分:1)

以下是使用JSON_TABLE()的示例:

select j.* from d, json_table(d.data, '$.a[*]' columns (
  color varchar(20) path '$.color', 
  value int path '$.value')
) as j;
+-------+-------+
| color | value |
+-------+-------+
| blue  |    15 |
| red   |    30 |
+-------+-------+

然后可以在WHERE子句中应用条件,就像您已将数据存储在普通表中一样。

select j.* from d, json_table(d.data, '$.a[*]' columns (
  color varchar(20) path '$.color', 
  value int path '$.value')
) as j 
where j.color = 'blue';
+-------+-------+
| color | value |
+-------+-------+
| blue  |    15 |
+-------+-------+

这要求您每次查询JSON数据时都编写类似这样的复杂查询。

一个人想知道从一开始将JSON存储在普通表中是否会更容易。

我经常建议MySQL用户,如果您需要使SQL表达式引用JSON中的各个字段,那么将数据存储为JSON将为您带来更多工作。在这些情况下,我将不使用JSON,将JSON数组分解为行,而将JSON字段分解为一组普通表的列。然后,您可以编写更简单的查询,可以使用索引进行优化,并且可以正确使用约束和数据类型。

JSON是最近的MySQL版本中最容易滥用的功能。