Reputation: 297
I need to create a list of JSON objects from properties in JSON object using MySQL 5.7. I have this structure:
{
"X": 1,
"Y": 1,
"Z": 55,
"A": 2,
"B": 33
}
I want to have the properties to be separated as objects and sorted by the keys in those objects like this:
[
{"A": 2},
{"B": 3},
{"X": 1},
{"Y": 1},
{"Z": 55}
]
I tried to separate keys and values and maybe then somehow merge it
TRIM(LEADING '[' FROM TRIM(TRAILING ']' FROM JSON_KEYS(letters_and_values))) as letters,
TRIM(LEADING '[' FROM TRIM(TRAILING ']' FROM JSON_EXTRACT(letters_and_values, '$.*'))) as values,
But I feel I'm complicating it. Does anyone know the easiest way to achieve the expected result?
Upvotes: 0
Views: 215
Reputation: 272106
No decent solution exists in MySQL 5.x for splitting JSON to rows for sorting. One ugly solution is to cross join with a table containing values 0, 1, 2, ...
and use JSON_EXTRACT(..., '$[...]')
to extract each item from JSON. Once you have each item on its row, you can sort and re-combine:
SELECT
CONCAT('[', GROUP_CONCAT(CONCAT('{', k, ':', v, '}') ORDER BY k DESC SEPARATOR ','), ']')
FROM (
SELECT
JSON_EXTRACT(JSON_KEYS(json), CONCAT('$[', i, ']')) AS k,
JSON_EXTRACT(json, CONCAT('$.', JSON_EXTRACT(JSON_KEYS(json), CONCAT('$[', i, ']')))) AS v
FROM t
INNER JOIN (
SELECT 0 AS i UNION ALL
SELECT 1 UNION ALL
SELECT 2 UNION ALL
SELECT 3 UNION ALL
SELECT 4 UNION ALL
SELECT 5 UNION ALL
SELECT 6 UNION ALL
SELECT 7 UNION ALL
SELECT 8 UNION ALL
SELECT 9
) AS numbers ON i < JSON_LENGTH(json)
) AS x
In MySQL 8 you can use JSON_TABLE
function to manipulate the JSON.
Note that the keys in JSON objects do not have any natural order. {"x": 1, "y": 2}
and {"y": 2, "x": 1}
are identical.
Upvotes: 2