I just installed MySQL 5.7.27 and I would like to use some Json fields so, I created some records, for example this value in a field:
{
\"Intitule\": {
\"n
Like i said, it can be a challenge parsing JSON in MySQL as you are dealing with text based keys here.
So you would need to use JSON_KEYS()
to get those in combination with a number generator a dynamic JSON path is generated to be used in JSON_EXTRACT()
MySQL 's 8 function JSON_TABLE()
makes it much much more easy..
Keep in mind this answer is purely meant for educational fun
Bill Karwin 's comment
You should either structure your JSON differently to support the search you need to do, or else you should not use JSON. Just store the data in multiple rows, and then
SELECT * FROM mytable WHERE is_filter = true
-
Query
SELECT
JSON_UNQUOTE(
JSON_EXTRACT(json , CONCAT('$.', SUBSTRING_INDEX(
SUBSTRING_INDEX(json_parsed, ',', number_generator.number)
, ','
, -1
), '.name'))) AS name
FROM (
SELECT
@row := @row + 1 AS number
FROM (
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row1
CROSS JOIN (
SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
) row2
CROSS JOIN (
SELECT @row := 0
) init_user_params
) AS number_generator
CROSS JOIN (
SELECT
SUBSTRING(json_keys, 2, json_keys_length - 2) AS json_parsed
, json_keys
, json
, JSON_LENGTH(json_keys) AS json_array_length
FROM (
SELECT
JSON_KEYS(record.json) AS json_keys
, json
, LENGTH(JSON_KEYS(record.json)) AS json_keys_length
FROM (
SELECT
'{
"Intitule": {
"name": "Intitule de la formation",
"stats": false,
"is_array": false,
"is_filter": true,
"chart": "pie",
"col": "6"
},
"Fin": {
"name": "Date de fin",
"stats": false,
"is_array": false,
"is_filter": false,
"chart": "pie",
"col": "6"
}
}' AS json
FROM
DUAL
) AS record
) AS json_information
) AS json_init
WHERE
number_generator.number BETWEEN 0 AND json_array_length
AND
JSON_EXTRACT(json , CONCAT('$.', SUBSTRING_INDEX(
SUBSTRING_INDEX(json_parsed, ',', number_generator.number)
, ','
, -1
), '.is_filter')) = true
Result
| name |
| ------------------------ |
| Intitule de la formation |
see demo
This answer is to expand on the comment I made above.
When you store data in non-relational format, you should understand that the structure of the data must serve the queries you need to run. You can't just store any data and expect it to be easy to query.
For example, if you need to search for the subdocument where is_filter
is true, then store your JSON like this:
{
"filter": {
"label": "Intitule",
"name": "Intitule de la formation",
"stats": false,
"is_array": false,
"chart": "pie",
"col": "6"
},
"not_filter": {
"label": "Fin",
"name": "Date de fin",
"stats": false,
"is_array": false,
"chart": "pie",
"col": "6"
}
}
If you need to use a variety of queries against the data, then using non-relational data like JSON is probably not as useful as storing the data in a relational manner.
mysql> select * from mytable;
+----------+--------------------------+-------+----------+-----------+-------+------+
| label | name | stats | is_array | is_filter | chart | col |
+----------+--------------------------+-------+----------+-----------+-------+------+
| Intitule | Intitule de la formation | 0 | 0 | 1 | pie | 6 |
| Fin | Date de fin | 0 | 0 | 0 | pie | 6 |
+----------+--------------------------+-------+----------+-----------+-------+------+
Then you can query by any attribute:
SELECT label FROM mytable WHERE is_filter = true;
NoSQL is more flexible than SQL for storing data.
SQL is more flexible than NoSQL for querying data.