简体   繁体   English

如何使用 MariaDB 从 JSON 数组中的多个对象中提取值?

[英]How can I use MariaDB to pull values from multiple objects from a JSON array?

In MariaDB 10.2.19, I have a table named forms with a column template which always contains a JSON array of objects.在 MariaDB 10.2.19 中,我有一个名为forms的表,其中包含一个列template ,该template始终包含一个 JSON 对象数组。 Some of these objects will have properties I want to return: name (should always be present), rule , and parameters .其中一些对象将具有我想要返回的属性: name (应始终存在)、 ruleparameters How can I return just these three properties from the entire array, but only for objects on which rule is present?我怎样才能从整个数组中只返回这三个属性,但只返回存在rule对象?

A sample array (formatted for easier viewing):示例数组(格式化以便于查看):

[{
    "label": "Employed?",
    "class": "select",
    "name": "employed",
    "parameters": "Yes",
    "rule": "in"
},
{
    "label": "Breed of dog?",
    "class": "select",
    "name": "breed",
    "parameters": "spaniel, collie, mix",
    "rule": "in"
},
{
    "label": "Number",
    "class": "text",
    "name": "breed"
}]

If you are using MySQL 8.0.4 or later one way is using JSON_TABLE :如果您使用 MySQL 8.0.4 或更高版本,一种方法是使用JSON_TABLE

mysql> SELECT * FROM foo;
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| data                                                                                                                                                                                                                                                                          |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| [{"name": "employed", "rule": "in", "class": "select", "label": "Employed?", "parameters": "Yes"}, {"name": "breed", "rule": "in", "class": "select", "label": "Breed of dog?", "parameters": "spaniel, collie, mix"}, {"name": "breed", "class": "text", "label": "Number"}] |
+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0,00 sec)

mysql> SELECT name, parameters 
         FROM foo,
              JSON_TABLE (
                  foo.data, 
                  "$[*]" COLUMNS (
                      name VARCHAR(100) PATH "$.name",
                      rule VARCHAR(100) PATH "$.rule",
                      parameters VARCHAR(100) PATH "$.parameters")
              ) AS t
       WHERE rule IS NOT NULL;
+----------+----------------------+
| name     | parameters           |
+----------+----------------------+
| employed | Yes                  |
| breed    | spaniel, collie, mix |
+----------+----------------------+
2 rows in set (0,00 sec)

https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html

You can accomplish this by using a dedicated numbers_table table:您可以使用专用的numbers_table表来完成此操作:

SELECT
    JSON_VALUE(f.template,CONCAT('$[',n.number,'].name')) AS `name`,
    JSON_VALUE(f.template,CONCAT('$[',n.number,'].rule')) AS `rule`,
    JSON_VALUE(f.template,CONCAT('$[',n.number,'].parameters')) AS `parameters`
FROM forms AS f
JOIN numbers_table AS n
WHERE
    n.number < JSON_LENGTH(f.template) AND
    JSON_VALUE(f.template,CONCAT('$[',n.number,'].rule')) IS NOT NULL;

The numbers_table table contains a single column called number which starts at 0 and can be as long as your use cases require (I have 1000 values 0 to 999 ). numbers_table表包含一个名为number列,它从0开始,并且可以根据您的用例需要(我有 1000 个值0999 )。 It is very useful for extracting each element of a JSON_ARRAY field into its own row.JSON_ARRAY字段的每个元素提取到其自己的行中非常有用。

The first WHERE condition makes sure we only use as many numbers as there are elements in the JSON_ARRAY ( template in your case).第一个WHERE条件确保我们只使用与JSON_ARRAY中的元素一样多的数字(在你的例子中是template )。

The second WHERE condition eliminates the ones that don't have a rule as per your use case.第二个WHERE条件根据您的用例消除了那些没有rule条件。

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

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