我有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获取此内容?
答案 0 :(得分:0)
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中的建议创建一个自己的聚合表,但我想这不是你的情况。
然而,正如两个答案中所提到的,似乎更好的是不在SQL数据库中存储这样的json列表。也许你可以创建一个相关的表,每个字典包含一行,然后用外键将它链接到你的主表。
答案 1 :(得分:0)
我正在一份报告中,其中一列中有一个大的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 ;
答案 2 :(得分:0)
我认为您没有使用表格。
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;
您可以通过对数组使用一些循环来匹配它们。我不知道这是否是最好的方法,但是它可以满足我的需求。
答案 3 :(得分:0)
您不使用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即可。