1

我有一个TABLBE

CREATE TABLE `saved_links` (
 `link_entry_id` bigint(20) NOT NULL AUTO_INCREMENT,
 `link_id` varchar(30) COLLATE utf8mb4_unicode_ci NOT NULL,
 `user_data_json` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
PRIMARY KEY (`link_entry_id`),
 UNIQUE KEY `link_id` (`link_id`)
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='saved Links'

并插入

INSERT INTO `saved_links`(`link_id`, `user_data_json` ) 
VALUES ( 
        'AABBCC',  
        '[{
            "mama@gmail_DOT_com": {"u_email": "mama@gmail_DOT_com", "private": "no"}}, 
          {
           "papa@gmail_DOT_com": {"u_email": "papa@gmail_DOT_com", "private": "no"}},
          {
           "daughter@gmail_DOT_com": {"u_email": "daughter@gmail_DOT_com", "private": "no"}},
          {
           "son@gmail_DOT_com": {"u_email": "son@gmail_DOT_com", "private": "no"}
        }]'  
    ), ( 
        'DDEEFF',  
            '[{
               "mama@gmail_DOT_com": {"u_email": "mama@gmail_DOT_com", "private": "no"}}, 
              {
               "papa@gmail_DOT_com": {"u_email": "papa@gmail_DOT_com", "private": "no"}} 
               
               ]'  
    ) ;

选择*

---------------------------------------------------
`link_id` | `user_data_json` 
----------------------------------------------------
`AABBCC` | [{
         |         "mama@gmail_DOT_com": {"u_email": "mama@gmail_DOT_com", "private": "no"}}, 
         |         {
         |          "papa@gmail_DOT_com": {"u_email": "papa@gmail_DOT_com", "private": "no"}},
         |         {
         |          "daughter@gmail_DOT_com": {"u_email": "daughter@gmail_DOT_com", "private": "no"}},
         |         {
         |          "son@gmail_DOT_com": {"u_email": "son@gmail_DOT_com", "private": "no"}}]
---------------------------------------------------------------------------------------------  
`DDEEFF` | [{
         |         "mama@gmail_DOT_com": {"u_email": "mama@gmail_DOT_com", "private": "no"}}, 
         |         {
         |          "papa@gmail_DOT_com": {"u_email": "papa@gmail_DOT_com", "private": "no"}}
         |         ]
---------------------------------------------------------------------------------------------    

     

我想删除"papa@gmail_DOT_com"和他所有valuesAABBCC

我已经尝试过(我正在使用 10.4.15-MariaDB)

    UPDATE `saved_links` 
      SET `user_data_json` = IFNULL( 
        JSON_REMOVE( `user_data_json`,  JSON_UNQUOTE( 
            REPLACE( JSON_SEARCH(
                `user_data_json`, 'all', 'papa@gmail_DOT_com', NULL, '$**.papa@gmail_DOT_com'), '.u_email', '' ) ) ), `user_data_json` )
 where `link_id` = 'AABBCC'  

这返回

 ---------------------------------------------------
    `link_id` | `user_data_json` 
    ----------------------------------------------------
    `AABBCC` | [{
             |         "mama@gmail_DOT_com": {"u_email": "mama@gmail_DOT_com", "private": "no"}}, 
             |         {}, //-> Notice these empty braces that are left behind.
             |         {
             |          "daughter@gmail_DOT_com": {"u_email": "daughter@gmail_DOT_com", "private": "no"}},
             |         {
             |          "son@gmail_DOT_com": {"u_email": "son@gmail_DOT_com", "private": "no"}}]

有没有办法避免{}删除后出现空?

UPDATE01-如果您尝试:

UPDATE `saved_links` SET 
`user_data_json` = 
      JSON_REMOVE(`user_data_json`, '$.papa@gmail_DOT_com') 
 WHERE  `link_id`= 'AABBCC'

这将删除列中的所有数据user_data_jsonWHERE link_id= 'AABBCC'`

谢谢

4

2 回答 2

1

我用这个谜题玩了一段时间,我想用另一种方法来做。您可以使用 json_search(加上其他功能)最终使用 json_remove。一旦您创建了一个 json 数组,我们必须考虑您的设计者决定按原样上传数据。所以,这是我的代码:

UPDATE saved_links sl 
SET user_data_json = 
JSON_REMOVE(user_data_json, 
    SUBSTRING_INDEX( 
        JSON_UNQUOTE( 
            JSON_SEARCH(sl.user_data_json,'one','papa@gmail_DOT_com') 
        )
    ,'.', 1) 
)
WHERE link_id='AABBCC'
  1. json_search(sl.user_data_json,'one','papa@gmail_DOT_com')

    • 退货"$[1].papa@gmail_DOT_com.u_email"
  2. JSON_UNQUOTE

    • 退货$[1].papa@gmail_DOT_com.u_email
  3. SUBSTRING_INDEX(@JSON,'.',1)

    • 退货$[1]
  4. 最后,您将使用最后一个返回作为 JSON_REMOVE 路径。

我不知道您的 JSON 密钥是否始终与 u_email 相同,但如果是真的,那么您可以使用它。

于 2021-05-18T03:59:36.070 回答
1

select json_remove(user_data_json,'$[1]') from saved_links where link_entry_id=19;

将返回:

[{"mama@gmail_DOT_com": {"private": "no", "u_email": "mama@gmail_DOT_com"}},
 {"daughter@gmail_DOT_com": {"private": "no", "u_email": "daughter@gmail_DOT_com"}},
 {"son@gmail_DOT_com": {"private": "no", "u_email": "son@gmail_DOT_com"}}]

我并没有真正使用 JSON,而是从这里的第二个示例中获得灵感:https ://mariadb.com/kb/en/json_remove/

编辑:

你可以优化这个:

with recursive abc as (
  Select 0 as i 
  union all 
  select i+1 from abc where i<2) 
select link_entry_id, link_id,i, json_keys(user_data_json,concat('$[',i,']')) 
from saved_links,abc;

输出:

+---------------+---------+------+----------------------------------------------+
| link_entry_id | link_id | i    | json_keys(user_data_json,concat('$[',i,']')) |
+---------------+---------+------+----------------------------------------------+
|            19 | AABBCC  |    0 | ["mama@gmail_DOT_com"]                       |
|            20 | DDEEFF  |    0 | ["mama@gmail_DOT_com"]                       |
|            19 | AABBCC  |    1 | ["papa@gmail_DOT_com"]                       |
|            20 | DDEEFF  |    1 | ["papa@gmail_DOT_com"]                       |
|            19 | AABBCC  |    2 | ["daughter@gmail_DOT_com"]                   |
|            20 | DDEEFF  |    2 | NULL                                         |
+---------------+---------+------+----------------------------------------------+

有了这个,您可以“转换”"papa@gm...."1.

EDIT2:结合来自MariadbMySQL的不同 JSON 函数可以做很多事情:

SELECT 
   j.person,
   JSON_KEYS(j.person), 
   JSON_EXTRACT(JSON_KEYS(j.person),'$[0]'), 
   JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(j.person),'$[0]')),
   JSON_VALUE(JSON_KEYS(j.person),'$[0]')
FROM 
   JSON_TABLE('[{
            "mama@gmail_DOT_com": {"u_email": "mama@gmail_DOT_com", "private": "no"}}, 
          {
           "papa@gmail_DOT_com": {"u_email": "papa@gmail_DOT_com", "private": "no"}},
          {
           "daughter@gmail_DOT_com": {"u_email": "daughter@gmail_DOT_com", "private": "no"}},
          {
           "son@gmail_DOT_com": {"u_email": "son@gmail_DOT_com", "private": "no"}
        }]', 
                  '$[*]' COLUMNS(person JSON PATH '$[0]')) j
                  

输出(请向右滚动,最后一列比第一列更有趣):

+ ----------- + ------------------------ + --------------------------------------------- + ----------------------------------------------------------- + ------------------------------------------- +
| person      | JSON_KEYS(j.person)      | JSON_EXTRACT(JSON_KEYS(j.person),'$[0]')      | JSON_UNQUOTE(JSON_EXTRACT(JSON_KEYS(j.person),'$[0]'))      | JSON_VALUE(JSON_KEYS(j.person),'$[0]')      |
+ ----------- + ------------------------ + --------------------------------------------- + ----------------------------------------------------------- + ------------------------------------------- +
| {"mama@gmail_DOT_com": {"private": "no", "u_email": "mama@gmail_DOT_com"}} | ["mama@gmail_DOT_com"]   | "mama@gmail_DOT_com"                          | mama@gmail_DOT_com                                          | mama@gmail_DOT_com                          |
| {"papa@gmail_DOT_com": {"private": "no", "u_email": "papa@gmail_DOT_com"}} | ["papa@gmail_DOT_com"]   | "papa@gmail_DOT_com"                          | papa@gmail_DOT_com                                          | papa@gmail_DOT_com                          |
| {"daughter@gmail_DOT_com": {"private": "no", "u_email": "daughter@gmail_DOT_com"}} | ["daughter@gmail_DOT_com"] | "daughter@gmail_DOT_com"                      | daughter@gmail_DOT_com                                      | daughter@gmail_DOT_com                      |
| {"son@gmail_DOT_com": {"private": "no", "u_email": "son@gmail_DOT_com"}} | ["son@gmail_DOT_com"]    | "son@gmail_DOT_com"                           | son@gmail_DOT_com                                           | son@gmail_DOT_com                           |
+ ----------- + ------------------------ + --------------------------------------------- + ----------------------------------------------------------- + ------------------------------------------- +

编辑(2020-12-26):我确实看过 mariadb,下面是在 version 上测试的10.5.8

select json_extract(json_array(user_data_json,"papa@gmail_DOT_com"), '$[1]') from saved_links;
+-----------------------------------------------------------------------+
| json_extract(json_array(user_data_json,"papa@gmail_DOT_com"), '$[1]') |
+-----------------------------------------------------------------------+
| "papa@gmail_DOT_com"                                                  |
| "papa@gmail_DOT_com"                                                  |
+-----------------------------------------------------------------------+

但是$[1]不希望使用 ,因此必须确定 的正确值1

WITH RECURSIVE data AS (
  SELECT 
    link_entry_id, 
    link_id, 
    0 as I, 
    JSON_KEYS(user_data_json, '$[0]') jk
  FROM saved_links
  UNION ALL
  SELECT 
    sl.link_entry_id, 
    sl.link_id, 
    I+1, 
    JSON_KEYS(user_data_json, CONCAT('$[',i+1,']')) 
  FROM saved_links sl, (select max(i) as I from data) x
  WHERE JSON_KEYS(user_data_json, CONCAT('$[',i+1,']'))<>'')
SELECT * FROM data
;

.

+---------------+---------+------+----------------------------+
| link_entry_id | link_id | I    | jk                         |
+---------------+---------+------+----------------------------+
|            19 | AABBCC  |    0 | ["mama@gmail_DOT_com"]     |
|            20 | DDEEFF  |    0 | ["mama@gmail_DOT_com"]     |
|            19 | AABBCC  |    1 | ["papa@gmail_DOT_com"]     |
|            20 | DDEEFF  |    1 | ["papa@gmail_DOT_com"]     |
|            19 | AABBCC  |    2 | ["daughter@gmail_DOT_com"] |
|            19 | AABBCC  |    3 | ["son@gmail_DOT_com"]      |
+---------------+---------+------+----------------------------+

I是找到的正确值papa@gmail_DOT_com

WITH RECURSIVE data AS (
  SELECT 
    link_entry_id, 
    link_id, 
    0 as I, 
    JSON_KEYS(user_data_json, '$[0]') jk
  FROM saved_links
  UNION ALL
  SELECT 
    sl.link_entry_id, 
    sl.link_id, 
    I+1, 
    JSON_KEYS(user_data_json, CONCAT('$[',i+1,']')) 
  FROM saved_links sl, (select max(i) as I from data) x
  WHERE JSON_KEYS(user_data_json, CONCAT('$[',i+1,']'))<>'')
SELECT 
   json_remove(user_data_json, concat('$[',I,']'))
FROM saved_links sl 
INNER JOIN data d ON d.link_entry_id= sl.link_entry_id AND d.link_id=sl.link_id and d.I=1
;

.

[{"mama@gmail_DOT_com": {"u_email": "mama@gmail_DOT_com", "private": "no"}},
      {"daughter@gmail_DOT_com": {"u_email": "daughter@gmail_DOT_com", "private": "no"}}, 
      {"son@gmail_DOT_com": {"u_email": "son@gmail_DOT_com", "private": "no"}}] 

[{"mama@gmail_DOT_com": {"u_email": "mama@gmail_DOT_com", "private": "no"}}] 
于 2020-12-13T16:29:27.833 回答