Mysql JSON 按键值更新

Mysql JSON update by value of a key

我有一个 table 喜欢:

CREATE TABLE `campus_tb` (
 `campus_id` int(11) NOT NULL AUTO_INCREMENT,
 `campus_dataJSON` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL CHECK (json_valid(`campus_dataJSON`)),
 PRIMARY KEY (`campus_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

INSERT INTO `campus_tb`( `campus_dataJSON`) VALUES ( '[
                          {"id":"100","u_email": "dr@kol.vop","name":"James","age":"17","course":"IT"},
                          {"id":"101","u_email": "meg@gmail.com","name":"Eric","age":"19","course":"CS"},
                          {"id":"102","u_email": "kitt@joko.com","name":"Julie","age":"21"}]')




+--------------------+-----------------------------------------------------------+
| campus_id          |  campus_dataJSON                                          | 
+--------------------+-----------------------------------------------------------+
| 1                  |  [
                     |     {"id":"100","u_email": "dr@kol.vop","name":"James","age":"17","course":"IT"},
                     |     {"id":"101","u_email": "meg@gmail.com","name":"Eric","age":"19","course":"CS"},
                     |     {"id":"102","u_email": "kitt@joko.com","name":"Julie","age":"21"}
                     |
                     |  ] 
----------------------------------------------------------------------------------  
| 2                  |  [
                     |     {"id":"12","u_email": "dr2@kol.vop","name":"Fomu","age":"17","course":"IT"},
                     |     {"id":"13","u_email": "meg2@gmail.com","name":"Jenga","age":"19","course":"CS"},
                     |     {"id":"18","u_email": "kitt2@joko.com","name":"Billie","age":"21"}
                     |
                     |  ] 
----------------------------------------------------------------------------------    

我正在使用 10.4.15-MariaDB

((1)) MySql 根据他们的 "email" WHERE campus_id = 1 查询更新学生的详细信息,例如我会喜欢添加 "admitted":"YES" where email = 'meg@gmail.com' AND campus_id=1

`{"id":"101","u_email": "meg@gmail.com","name":"Eric","age":"19","course":"CS", "admitted":"YES" }`

((2)) Mysql 查询更新从 "age":"21""age":"25" 其中 email = 'kitt@joko.com'campus_id=1

This is what I have tried so far for both ((1)) and ((2)):

UPDATE `campus_tb` set `campus_dataJSON` = JSON_SET( `campus_dataJSON` , json_unquote(json_search( `campus_dataJSON` , 'one', 'dr@kol.vop')), JSON_MERGE(`campus_dataJSON`,'$.admitted','YES') ) where `campus_id` = 1 //Strangely, this clears out all data in the column.

UPDATE `campus_tb` set `campus_dataJSON`  = JSON_MERGE(   `campus_dataJSON`  ,    json_unquote(json_search(`campus_dataJSON`  , 'one', 'meg@gmail.com')),   JSON_OBJECT('$.admitted','YES')) where `campus_id` =1;

UPDATE `campus_tb` set `campus_dataJSON`  =  = JSON_INSERT(`campus_dataJSON` , '$.admitted', "YES") WHERE `campus_dataJSON`->'$.u_email' = 'dr@kol.vop'; // this returns ERROR near '>u_email'


 UPDATE `campus_tb` set `campus_dataJSON`  =  = JSON_SET(`campus_dataJSON` , '$.age', "25") WHERE `campus_dataJSON`->'$.u_email' = 'kitt@joko.com'; // this returns same ERROR near '>email'

来自其他网站的示例

我看到了这个

UPDATE players SET player_and_games = JSON_INSERT(player_and_games, '$.games_played.Puzzler', JSON_OBJECT('time', 20)) WHERE player_and_games->'$.name' = 'Henry';  

来自此站点:https://www.compose.com/articles/mysql-for-your-json/

但使用相同的方法会抛出错误:You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '>'$.email' = '

因为这个 `campus_dataJSON`->'$.u_email' = 'dr@kol.vop' 抛出一个错误:

mysql> select json_search(campus_dataJSON,'one','dr@kol.vop') from campus_tb;
+-------------------------------------------------+
| json_search(campus_dataJSON,'one','dr@kol.vop') |
+-------------------------------------------------+
| "$[0].u_email"                                  |
+-------------------------------------------------+
1 row in set (0.00 sec)

mysql> select campus_dataJSON->'$[0].u_email' from campus_tb;
+---------------------------------+
| campus_dataJSON->'$[0].u_email' |
+---------------------------------+
| "dr@kol.vop"                    |
+---------------------------------+
1 row in set (0.00 sec)

mysql> select json_unquote(campus_dataJSON->'$[0].u_email') from campus_tb;
+-----------------------------------------------+
| json_unquote(campus_dataJSON->'$[0].u_email') |
+-----------------------------------------------+
| dr@kol.vop                                    |
+-----------------------------------------------+
1 row in set (0.00 sec)

mysql>

编辑:这会将 campus_id=1 中用户的 age 更新为 25,电子邮件地址为“meg@gmail.com”

WITH RECURSIVE abc as (
    SELECT 0 as i
    UNION ALL
    SELECT i+1 FROM abc WHERE i<10), -- See note!
    data as (
    SELECT 
    i,
    campus_id as campus,
    json_unquote(json_extract(campus_dataJSON,CONCAT("$[",i,"].id"))) as id,
    json_unquote(json_extract(campus_dataJSON,CONCAT("$[",i,"].name"))) as name,
    json_unquote(json_extract(campus_dataJSON,CONCAT("$[",i,"].u_email"))) as email,
    json_unquote(json_extract(campus_dataJSON,CONCAT("$[",i,"].age"))) as age
    FROM abc
    CROSS JOIN campus_tb 
    WHERE not json_extract(campus_dataJSON,CONCAT("$[",i,"].id")) is null)
UPDATE `campus_tb`,`data` 
SET campus_dataJSON = json_set(campus_dataJSON,CONCAT('$[',i,'].age'),25)
WHERE campus_id = campus and campus=1 and email="meg@gmail.com"
;

cte data procuces, when doing SELECT * from data:

+------+--------+------+-------+---------------+------+
| i    | campus | id   | name  | email         | age  |
+------+--------+------+-------+---------------+------+
|    0 |      1 | 100  | James | dr@kol.vop    | 17   |
|    0 |      2 | 100  | James | dr@kol.vop    | 17   |
|    1 |      1 | 101  | Eric  | meg@gmail.com | 25   |
|    1 |      2 | 101  | Eric  | meg@gmail.com | 19   |
|    2 |      1 | 102  | Julie | kitt@joko.com | 21   |
|    2 |      2 | 102  | Julie | kitt@joko.com | 21   |
+------+--------+------+-------+---------------+------+

注意:人数10应设置为大于校园内最大学生人数。

@nbk 从另一个聊天室帮助我

对于 ((1)): 添加 "admitted":"YES" 其中 email = 'meg@gmail.com'

UPDATE campus_tb
SET `campus_dataJSON` = 
JSON_INSERT(`campus_dataJSON`, CONCAT(REPLACE(SUBSTRING_INDEX(JSON_SEARCH(`campus_dataJSON`, 'one', 'meg@gmail.com'),'.',1),'"',''),'.admitted'), 'YES')
WHERE campus_id = 1;

RESULT: {"id": "101", "u_email": "meg@gmail.com", "name": "Eric", "age": "19", "course": "CS", "admitted": "YES"}

对于 ((2)):"age":"21" 更新到 "age":"25" 其中 email = 'kitt@joko.com'campus_id=1

UPDATE campus_tb
SET `campus_dataJSON` 
=  JSON_REPLACE(`campus_dataJSON`, CONCAT(REPLACE(SUBSTRING_INDEX(JSON_SEARCH(`campus_dataJSON`, 'one', 'kitt@joko.com'),'.',1),'"',''),'.age'), 35)
WHERE campus_id = 1;

RESULT: {"id": "102", "u_email": "kitt@joko.com", "name": "Julie", "age": 35}