Reputation: 259
In MariaDB 10.2.19, I have a table named forms
with a column template
which always contains a JSON array of objects. Some of these objects will have properties I want to return: name
(should always be present), rule
, and parameters
. How can I return just these three properties from the entire array, but only for objects on which rule
is present?
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"
}]
Upvotes: 0
Views: 895
Reputation: 13
You can accomplish this by using a dedicated numbers_table
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
). It is very useful for extracting each element of a JSON_ARRAY
field into its own row.
The first WHERE
condition makes sure we only use as many numbers as there are elements in the JSON_ARRAY
(template
in your case).
The second WHERE
condition eliminates the ones that don't have a rule
as per your use case.
Upvotes: 0
Reputation: 15969
If you are using MySQL 8.0.4 or later one way is using 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
Upvotes: 1