I have following tables and their relationship. I am storing JSON data in client_services table. Is their any way to retrieve JSON values using MySQL query like this:
SELECT getJson("quota") as quota, client_id FROM client_services WHERE service_id = 1;
Or can I normalize client_services table further?
Table Services
:
+----+-----------------------+--------------------------------------------------------+ | id | name | description | +----+-----------------------+--------------------------------------------------------+ | 1 | MailBox | | | 2 | SMS | | | 3 | FTP | | +----+-----------------------+--------------------------------------------------------+
Table service_features
:
+----+------------+----------------------------------+------------------------+ | id | service_id | name | description | +----+------------+----------------------------------+------------------------+ | 10 | 1 | Forwarding | Forward Mail | | 11 | 1 | Archive | Archive Mail | | 12 | 1 | WebMail | NULL | | 13 | 1 | IMAP | NULL | | 14 | 2 | Web SMS | NULL | +----+------------+----------------------------------+------------------------+
Table client_services
:
+-----+-----------+------------+-------------------------------------------------------------------------------------------+ | id | client_id | service_id | service_values | +-----+-----------+------------+-------------------------------------------------------------------------------------------+ | 100 | 1000 | 1 |{ "quota": 100000,"free_quota":20000,"total_accounts":200,"data_transfer":1000000} | | 101 | 1000 | 2 |{ "quota": 200 } | | 102 | 1000 | 3 |{ "data_transfer":1000000} | | 103 | 1001 | 1 |{ "quota": 1000000,"free_quota":2000,"total_accounts":200,"data_transfer":1000000} | | 104 | 1001 | 2 |{ "quota": 500 } | | 105 | 1002 | 2 |{ "quota": 600 } | +-----+-----------+------------+-------------------------------------------------------------------------------------------+
Table client_feature_mappers
:
+-----+-------------------+--------------------+-----------+ | id | client_service_id | service_feature_id | client_id | +-----+-------------------+--------------------+-----------+ |10000| 100| 10 | 1000| |10001| 100| 11 | 1000| |10002| 100| 12 | 1000| |10003| 100| 13 | 1000| |10004| 101| 14 | 1000| |10005| 103| 10 | 1001| |10006| 101| 11 | 1001| |10007| 101| 12 | 1001| |10008| 101| 13 | 1001| |10009| 105| 14 | 1002| +-----+-------------------+--------------------+-----------+
In MySQL, the JSON_EXTRACT() function returns data from a JSON document. The actual data returned is determined by the path you provide as an argument. You provide the JSON document as the first argument, followed by the path of the data to return.
MySQL supports a native JSON data type defined by RFC 7159 that enables efficient access to data in JSON (JavaScript Object Notation) documents. The JSON data type provides these advantages over storing JSON-format strings in a string column: Automatic validation of JSON documents stored in JSON columns.
Exporting MySQL data to JSON using the CONCAT() and GROUP_CONCAT() functions. Using a combination of CONCAT() and GROUP_CONCAT() functions, data from SQL string can be converted into JSON format.
Since a lot of people have asked this question to me personally, I thought I would give this answer a second revision. Here is a gist that has the complete SQL with SELECT, Migration and View Creation and a live sql fiddle (availability not guaranteed for fiddle).
Let's say you have table (named: TBL_JSON) like this:
ID CITY POPULATION_JSON_DATA ----------------------------------------------------------------------- 1 LONDON {"male" : 2000, "female" : 3000, "other" : 600} 2 NEW YORK {"male" : 4000, "female" : 5000, "other" : 500}
To Select each json fields, you may do:
SELECT ID, CITY, json_extract(POPULATION_JSON_DATA, '$.male') AS POPL_MALE, json_extract(POPULATION_JSON_DATA, '$.female') AS POPL_FEMALE, json_extract(POPULATION_JSON_DATA, '$.other') AS POPL_OTHER FROM TBL_JSON;
which results:
ID CITY POPL_MALE POPL_FEMALE POPL_OTHER ----------------------------------------------------------------- 1 LONDON 2000 3000 600 2 NEW YORK 4000 5000 500
This might be an expensive operation to run based on your data size and json complexity. I suggest using it for
Watch out for: You may have json starting with double quotes (stringified):
"{"male" : 2000, "female" : 3000, "other" : 600}"
Tested with Mysql 5.7 on Ubuntu and Mac OSX Sierra.
You can use MySQL function SUBSTRING_INDEX to break down the JSON string:
SELECT SUBSTRING_INDEX( SUBSTRING_INDEX( SUBSTRING_INDEX( service_values, 'quota', -1), '": ', -1), ' ', 1) AS quota, client_id FROM client_services WHERE service_id=1;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With