Reputation: 10312
From MySQL JSON data field, I'm extracting data from array like so:
SELECT
data ->> '$.fields[*]' as fields
FROM some_database...
which returns:
[{
"id": 111056,
"hint": null,
"slug": "email",
"label": "E-mail",
"value": null,
"field_value": "[email protected]",
"placeholder": null
}, {
"id": 111057,
"hint": null,
"slug": "name",
"label": "Imię",
"value": null,
"field_value": "Aneta",
"placeholder": null
}]
I can also extract single column:
SELECT
data ->> '$.fields[*].field_value' as fields
FROM some_database...
and that returns the following result:
[[email protected], Aneta]
But how can I extract field_value
alongside with label
as key-pairs?
Preferred output would be a single multi-row string containing pairs:
label: field_value
label: field_value
...
Using example shown above it would get me following output:
E-mail: [email protected]
Imię: Aneta
One-liner preferred as I have multiple of such arrays to extract from various fields.
Upvotes: 2
Views: 4819
Reputation: 1199
You can use JSON_VALUE:
select JSON_VALUE (json_value_col, '$.selected_key') as selected_value from user_details ;
You can also use JSON_EXTRACT:
select JSON_EXTRACT (json_value_col, '$.selected_key') as selected_value from user_details ;
For more details refer: https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html
Upvotes: 0
Reputation: 562250
Here's an example of extracting the key names as rows:
select j.keyname from some_database
cross join json_table(
json_keys(data->'$[0]'),
'$[*]' columns (
keyname varchar(20) path '$'
)
) as j;
Output:
+-------------+
| keyname |
+-------------+
| id |
| hint |
| slug |
| label |
| value |
| field_value |
| placeholder |
+-------------+
Now you can join that to the values:
select n.n, j.keyname,
json_unquote(json_extract(f.data, concat('$[', n.n, ']."', j.keyname, '"'))) as value
from some_database as d
cross join json_table(
json_keys(d.data->'$[0]'),
'$[*]' columns (
keyname varchar(20) path '$'
)
) as j
cross join n
join some_database as f on n.n < json_length(f.data);
Output:
+---+-------------+------------------+
| n | keyname | value |
+---+-------------+------------------+
| 0 | id | 111056 |
| 0 | hint | null |
| 0 | slug | email |
| 0 | label | E-mail |
| 0 | value | null |
| 0 | field_value | [email protected] |
| 0 | placeholder | null |
| 1 | id | 111057 |
| 1 | hint | null |
| 1 | slug | name |
| 1 | label | Imię |
| 1 | value | null |
| 1 | field_value | Aneta |
| 1 | placeholder | null |
+---+-------------+------------------+
I'm using a utility table n
which is just filled with integers.
create table n (n int primary key);
insert into n values (0),(1),(2),(3)...;
If this seems like a lot of complex work, then maybe the lesson is that storing data in JSON is not easy, when you want SQL expressions to work on the discrete fields within JSON documents.
Upvotes: 6