【问题标题】:MySQL 5 join from integers in json arrayMySQL 5 从 json 数组中的整数连接
【发布时间】:2021-03-29 14:52:24
【问题描述】:

有什么方法可以用 MySQL 5 完成这个吗?

我有两个表 usersroles

用户

 desc users;
+-------+---------+------+-----+---------+-------+
| Field | Type    | Null | Key | Default | Extra |
+-------+---------+------+-----+---------+-------+
| id    | int(11) | YES  |     | NULL    |       |
| data  | json    | YES  |     | NULL    |       |
+-------+---------+------+-----+---------+-------+
2 rows in set (0.00 sec)


 select * from users;
 +------+------------------------------------+
 | id   | data                               |
 +------+------------------------------------+
 |    1 | {"name": "cat", "roleIds": [2, 3]} |
 |    2 | {"name": "dog", "roleIds": [1, 4]} |
 |    3 | {"name": "mouse", "roleIds": [5]}  |
 +------+------------------------------------+
 3 rows in set (0.00 sec)

角色

desc roles;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| role_id | int(11)     | NO   |     | 0       |       |
| name    | varchar(64) | NO   |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

select * from roles;
+---------+-------------+
| role_id | name        |
+---------+-------------+
|       1 | Admin       |
|       2 | Supervisor  |
|       3 | Provisioner |
|       4 | Operator    |
|       5 | Relief      |
+---------+-------------+
5 rows in set (0.01 sec)

我想用角色名修改users表中的json数据 结果看起来像这样

+------+------------------------------------------------------------------------------+
| id   | data                                                                         |
+------+------------------------------------------------------------------------------+
|    1 | {"name": "cat", "roleIds": [2, 3], "roleNames": "[Supervisor, Provisioner]"} |
|    2 | {"name": "dog", "roleIds": [1, 4], "roleNames": "[Admin, Operator]"}         |
|    3 | {"name": "mouse", "roleIds": [5], "roleNames": "[Relief]"}                   |
+------+------------------------------------------------------------------------------+

【问题讨论】:

  • 如果架构被正确规范化,那就容易多了……

标签: mysql sql arrays json inner-join


【解决方案1】:

这是一种使用json_set()json_contains()json_arrayagg() 的方法,它们都在 MySQL 5.7 中可用(后者在 5.7.22 版本中引入):

select u.id,
    json_set(
        u.data,
        '$.roleNames', (
            select json_arrayagg(r.name)
            from roles r
            where json_contains(u.data, cast(r.role_id as json), '$.roleIds')
        )
    ) as data
from users u

Demo on DB Fiddle

id data
1 {"name": "cat", "roleIds": [2, 3], "roleNames": ["Supervisor", "Provisioner"]}
2 {"name": "dog", "roleIds": [1, 4], "roleNames": ["Admin", "Operator"]}
3 {"name": "mouse", "roleIds": [5], "roleNames": ["Relief"]}

需要指出的是,MySQL不保证元素在json_arrayagg()生成的数组中出现的顺序。这是我们在当前数据库版本中必须忍受的限制。

【讨论】:

  • 不幸的是我发现我必须使用 MySQL 5.7.12。 JSON_ARRAYAGG 直到 5.7.22 才出来。没有那个命令有什么办法吗?谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-05-30
  • 2021-12-30
  • 1970-01-01
  • 2017-03-14
  • 1970-01-01
  • 1970-01-01
  • 2013-08-22
  • 1970-01-01
相关资源
最近更新 更多