【问题标题】:MySQL Return JSON array index based on property valueMySQL根据属性值返回JSON数组索引
【发布时间】:2022-01-12 21:46:26
【问题描述】:

我有一个这样的 JSON 数据表:

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

我需要获取与“蓝色”相同的对象内的“值”。

我想用下面的代码:

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

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

那么,有没有办法先检索索引,然后我会使用正确的索引进行查询?

更新

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

【问题讨论】:

  • 您能发布带有标记和所有内容的完整解决方案吗?

标签: mysql json


【解决方案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 版本中最容易被滥用的特性。

【讨论】:

  • 我同意您对 JSON 数据类型有用性的评估。从理论上讲,这似乎是一个好主意,但在实践中,这似乎是一场噩梦(不是从个人经验来说,只是从尝试回答关于 SO 的问题)。
  • JSON 的实现是为了满足市场需求。 MongoDB 有,PostgreSQL 有,even Informix has a BSON data type。开发人员一直要求“灵活性”将非结构化数据倒入他们的数据库,因为他们无法定义具体的模式。通常这也不是他们的错,因为他们正在制定的产品规范不会提供足够的具体细节来定义模式。
  • 是的,我明白为什么会发生这样的妥协。嗯,这比我几年前在 Invision Power Board 源代码中看到的要好——它们以 PHP serialize() 格式存储一些选项,并使用 LIKERLIKE 来搜索匹配项。
  • 哎哟。这听起来像是problem with regular expressions 的经典示例。
【解决方案2】:

使用JSON_SEARCH() 查找blue 的路径。

SELECT JSON_EXTRACT(my_data, REPLACE(JSON_SEARCH(my_data, 'one', 'blue'), '.color', '.value'))

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

【讨论】:

  • 感谢您的回复。你测试了吗?因为我收到“无效的 JSON 路径表达式。错误在字符位置 1 附近。”。但我会试着用你的解释来解决这个问题
  • 不,我没有支持 JSON 的 MySQL 版本。
  • 看来JSON路径必须是文字,不能使用计算路径的表达式。
  • 避免在 MySQL 中使用 JSON 的另一个原因。它使您的架构非规范化,并且功能非常繁琐且有限。
  • 你的回答很有用,它可以在 JSON_UNQUOTE() 中包装句子
猜你喜欢
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
  • 2017-03-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多