'Print key, value pairs from nested MYSQL json

I have extracted a mysql json dictionary strucutre and I wish to get all the values associated with the keys alpha and beta; however I also wish to print the key too. The structure of the dictionary is:

results = 
{1:
    {"a": {"alpha": 1234,
         "beta": 2345},
     "b": {"alpha": 1234,
         "beta": 2345},
     "c": {"alpha": 1234,
         "beta": 2345},
    },
 2: 
    {"ab": {"alpha": 1234,
          "beta": 2345},
     "ac": {"alpha": 1234,
          "beta": 2345},
     "bc": {"alpha": 1234,
          "beta": 2345},
    },
 3:
    {"abc": {"alpha": 1234,
           "beta": 2345}
    }
 "random_key": "not_interested_in_this_value"
}

So far I have been had some succes extracting the data I wish using:

SELECT JSON_EXTRACT alpha, beta FROM results;

This gave me the alpha and beta columns; however, I ideally would like to assoicate each value with their key to get:

+-------+---------+---------+
| key   | alpha   | beta    |
+-------+---------+---------+
| a     | 1234.   | 2345.   |
| b     | 1234.   | 2345.   |
| c     | 1234.   | 2345.   |
| ab    | 1234.   | 2345.   |
| ac    | 1234.   | 2345.   |
| bc    | 1234.   | 2345.   |
| abc   | 1234.   | 2345.   |
+-------+---------+---------+

I am very new to mysql and any help is appreciated.



Solution 1:[1]

First of all, what you posted is not valid JSON. You can use integers as values, but you can't use integers as keys in objects. Also you have a few spurious , symbols. I had to fix these mistakes before I could insert the data into a table to test.

I was able to solve this using MySQL 8.0's JSON_TABLE() function in the following way:

select
 j2.`key`,
 json_extract(results, concat('$."',j1.`key`,'"."',j2.`key`,'".alpha')) as alpha,
 json_extract(results, concat('$."',j1.`key`,'"."',j2.`key`,'".beta')) as beta
from mytable
cross join json_table(json_keys(results), '$[*]' columns (`key` int path '$')) as j1
cross join json_table(json_keys(json_extract(results, concat('$."',j1.`key`,'"'))), '$[*]' columns (`key` varchar(3) path '$')) as j2
where j2.`key` IS NOT NULL;

Output:

+------+-------+------+
| key  | alpha | beta |
+------+-------+------+
| a    | 1234  | 2345 |
| b    | 1234  | 2345 |
| c    | 1234  | 2345 |
| ab   | 1234  | 2345 |
| ac   | 1234  | 2345 |
| bc   | 1234  | 2345 |
| abc  | 1234  | 2345 |
+------+-------+------+

If you find this sort of query too difficult, I would encourage you to reconsider whether you want to store data in JSON.

If I were you, I'd store data in normal rows and columns, then the query would be a lot simpler and easier to write and maintain.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1