【问题标题】:How to JSON extract from dynamic key value pair in MySQL?如何从 MySQL 中的动态键值对中提取 JSON?
【发布时间】:2018-05-05 01:28:38
【问题描述】:

我有带有 user_id 和 user_details 的用户表。它包含字符串格式的 JSON 数据,如下所示:

[{"name":"question-1","value":"sachin","label":"Enter your name?"},
    {"name":"question-2","value":"abc@example.com","label":"Enter your email?"},
    {"name":"question-3","value":"xyz","label":"Enter your city?"}]

我尝试过使用 json_extract,但如果 json 有数据,它会返回结果,如下所示:

{"name":"question-1","value":"sachin","label":"Enter your name?"}

然后它返回结果为,

    Name    |     Label
question-1  |   Enter your name? 

预期结果: 我想在 sql 查询中从 json 中提取所有名称和标签。

示例 1: 假设我们在 user_details 列中有以下数据,

[{"name":"question-1","value":"sachin","label":"Enter your name?"},
    {"name":"question-2","value":"abc@example.com","label":"Enter your email?"},
    {"name":"question-3","value":"xyz","label":"Enter your city?"}]

那么sql查询应该返回以下格式的结果,

    Name      |     Label
question-1    |  Enter your name?
question-2    |  Enter your email?
question-3    |  Enter your city?

如何在 MySQL 中使用 JSON_EXTRACT 获得这个?

【问题讨论】:

    标签: mysql json


    【解决方案1】:

    我假设您没有使用表格。

    SET @data = '[{"name":"question-1","value":"sachin","label":"Enter your name?"},
        {"name":"question-2","value":"abc@example.com","label":"Enter your email?"},
        {"name":"question-3","value":"xyz","label":"Enter your city?"}]';
    
    SELECT JSON_EXTRACT(@data,'$[*].name') AS "name", JSON_EXTRACT(@data,'$[*].label') AS "label";
    

    它会返回

    name                                           |  label
    ["question-1", "question-2", "question-3"]     |  ["Enter your name?", "Enter your email?", "Enter your city?"]
    

    根据您的表和列名,SQL 应该如下所示:

    SELECT JSON_EXTRACT(user_details,'$[*].name') AS "name", JSON_EXTRACT(user_details,'$[*].label') AS "label" FROM user;
    

    您可以通过对数组使用一些循环来匹配它们。我不知道这是否是最好的方式,但它满足了我的需求。

    【讨论】:

      【解决方案2】:

      How to extract rows from a json array using the mysql udf json_extract 0.4.0? 给出的另一个答案是使用 common_schema 解析自己的 JSON。如果您不习惯复杂的 SQL,那就相当棘手了。

      如果您知道该字段将给出多少个元素,您可以按照主题 List all array elements of a MySQL JSON field 中的建议创建自己的聚合表,但我想这不是您的情况。

      但是,正如两个答案中提到的,最好不要将此类 json 列表存储在 SQL 数据库中。也许您可以创建一个相关表,其中每个字典包含一行,然后使用外键将其链接到您的主表。

      【讨论】:

        【解决方案3】:

        我正在编写一份报告,其中有一列中有一个很大的 json 数组列表。我修改了数据模型以将关系 1 存储到 * 而不是将所有内容存储在一个列中。为了完成这个过程,我不得不在存储过程中使用一段时间,因为我不知道最大大小:

        DROP PROCEDURE IF EXISTS `test`;
        
        DELIMITER #
        
        CREATE PROCEDURE `test`()
        PROC_MAIN:BEGIN
        DECLARE numNotes int;
        DECLARE c int;
        DECLARE pos varchar(10);
        
        SET c = 0;
        SET numNotes = (SELECT 
        ROUND (   
                (
                    LENGTH(debtor_master_notes)
                    - LENGTH( REPLACE ( debtor_master_notes, "Id", "") ) 
                ) / LENGTH("Id")        
            ) AS countt FROM debtor_master
        order by countt desc Limit 1);
        
        DROP TEMPORARY TABLE IF EXISTS debtorTable;
        CREATE TEMPORARY TABLE debtorTable(debtor_master_id int(11), json longtext, note int);
        WHILE(c <numNotes) DO
        SET pos = CONCAT('$[', c, ']');
        INSERT INTO debtorTable(debtor_master_id, json, note)
        SELECT debtor_master_id, JSON_EXTRACT(debtor_master_notes, pos), c+1
        FROM debtor_master
        WHERE debtor_master_notes IS NOT NULL AND debtor_master_notes like '%[%' AND JSON_EXTRACT(debtor_master_notes, pos) IS NOT NULL AND JSON_EXTRACT(debtor_master_notes, pos) IS NOT NULL;
        SET c = c + 1;
        END WHILE;
        SELECT * FROM debtorTable;
        END proc_main #
        
        DELIMITER ;
        

        【讨论】:

          【解决方案4】:

          您不使用 JSON_EXTRACT()。你用JSON_TABLE():

          mysql> create table mytable ( id serial primary key, data json);
          Query OK, 0 rows affected (0.01 sec)
          
          mysql> insert into mytable set data = '[{"name":"question-1","value":"sachin","label":"Enter your name?"},
              '>     {"name":"question-2","value":"abc@example.com","label":"Enter your email?"},
              '>     {"name":"question-3","value":"xyz","label":"Enter your city?"}]';
          Query OK, 1 row affected (0.00 sec)
          
          mysql> SELECT j.* FROM mytable,
            JSON_TABLE(data, '$[*]' COLUMNS (
              name VARCHAR(20) PATH '$.name', 
              label VARCHAR(50) PATH '$.label'
            )) AS j;
          +------------+-------------------+
          | name       | label             |
          +------------+-------------------+
          | question-1 | Enter your name?  |
          | question-2 | Enter your email? |
          | question-3 | Enter your city?  |
          +------------+-------------------+
          

          JSON_TABLE() 需要 MySQL 8.0.4 或更高版本。如果您至少没有运行该版本,则必须升级。

          老实说,如果您需要访问各个字段,将数据存储在普通列中并避免使用 JSON 会减少工作量。

          【讨论】:

            猜你喜欢
            • 2019-02-27
            • 2021-09-24
            • 1970-01-01
            • 1970-01-01
            • 2019-02-05
            • 2016-12-24
            • 1970-01-01
            • 2020-05-03
            • 1970-01-01
            相关资源
            最近更新 更多