您可以在 MySQL 8.0 中执行此操作JSON_TABLE():
select r.res from mytable,
json_table(mytable.content, '$[*]' columns (res int path '$')) r
where mytable.id = 1
我在 MySQL 8.0.17 上进行了测试,这是输出:
+------+
| res |
+------+
| 3 |
| 4 |
+------+
如果您使用 MySQL 8.0 之前的版本,您有以下选项:
- 找到一些极其复杂的 SQL 解决方案。这几乎总是解决问题的错误方法,因为您最终会得到维护成本太高的代码。
- 按原样获取 JSON 数组,并在应用程序代码中分解它。
- 规范化数据,以便每行都有一个值,而不是使用 JSON 数组。
我经常在 Stack Overflow 上找到有关在 MySQL 中使用 JSON 的问题,这些问题让我相信这个功能已经毁了 MySQL。开发人员继续不恰当地使用它。他们喜欢这样很容易insert半结构化数据,但他们发现它使得querying这些数据太复杂了。
回复 @ChetanOswal 的评论:
MySQL 5.7 有一些解决方案,但它们并不令人满意,我的建议是避免使用它们。
Demo:
我们可以从上面原始问题中显示的数据开始。
mysql> create table mytable (id serial primary key, content json);
mysql> insert into mytable values
-> (1, '[3,4]'),
-> (2, '[5,6]');
接下来,我们需要另一个表,它只包含一系列整数值,至少与最长的 JSON 数组一样多。
mysql> create table numbers (number int primary key);
mysql> insert into numbers values (0), (1), (2);
使用不等式连接这些表,我们可以创建与 JSON 数组中的项目数一样多的行。
mysql> select * from mytable
join numbers on numbers.number < json_length(mytable.content);
+----+---------+--------+
| id | content | number |
+----+---------+--------+
| 1 | [3, 4] | 0 |
| 1 | [3, 4] | 1 |
| 2 | [5, 6] | 0 |
| 2 | [5, 6] | 1 |
+----+---------+--------+
现在我们可以使用这些数字作为数组索引来从 JSON 数组中提取值。
mysql> select *,
json_extract(mytable.content, concat('$[', numbers.number, ']')) as value
from mytable
join numbers on numbers.number < json_length(mytable.content);
+----+---------+--------+-------+
| id | content | number | value |
+----+---------+--------+-------+
| 1 | [3, 4] | 0 | 3 |
| 1 | [3, 4] | 1 | 4 |
| 2 | [5, 6] | 0 | 5 |
| 2 | [5, 6] | 1 | 6 |
+----+---------+--------+-------+
这就是我在 MySQL 5.7 中解决这个问题的建议。
如果您需要 MySQL 8.0 中的功能,那么您应该升级到 MySQL 8.0。
MySQL 5.7 将于 2023 年 10 月即将结束生命。无论如何,是时候升级了。
如果您无法升级,并且您不喜欢我展示的解决方案,那么您应该停止使用 SQL 来处理 JSON。