繁体   English   中英

如何从MySQL中的动态键值对JSON提取?

[英]How to JSON extract from dynamic key value pair in MySQL?

我有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 udf json_extract 0.4.0从json数组提取行给出的另一个答案 是用common_schema解析自己的JSON。 如果您不习惯复杂的SQL,那将非常棘手。

如果您知道该字段将给出多少个元素,则可以按照主题列出MySQL JSON字段的所有数组元素中的建议创建自己的聚合表,但是我想这不是您的情况。

但是,正如两个答案中所述,似乎最好不要在您的SQL数据库中存储这样的json列表。 也许您可以制作一个相关的表,每个字典包含一行,然后用外键将其链接到主表。

我正在一份报告中工作,其中一列中有一个很大的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 ;

我假设您没有使用表。

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;

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

您不使用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的工作就更少了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM