Exporting MySql table into JSON Object - mysql

how to convert my mysql table result into json Object in database level
for example ,
SELECT json_array(
group_concat(json_object( name, email))
FROM ....
it will produce the result as
[
{
"name": "something",
"email": "someone#somewhere.net"
},
{
"name": "someone",
"email": "something#someplace.com"
}
]
but what i need is i need to given my own query which may contains functions, subqueries etc.
like in postgres select row_to_json(select name,email,getcode(branch) from .....) then i will get the whole result as json object
in mysql is there any possibilities to do like this?
select jsonArray(select name,email,getcode(branch) from .....)

I only found in official Mysql 8 and 5.7 documentation that it supports casting to JSON type. It includes a JSON_ARRAY function in MySQL 8 and 5.7, and JSON_ARRAYAGG function in MySQL 8. Please see the full JSON functions reference here.
It means that does not exist an easy mysql built-in solution to the problem.
Fortunately, our colleagues started a similar discussion here. Maybe you could find your solution there.
For one searching for well-defined attributes JSON casting, the solution is here.

Related

Apache Drill: Two Lateral Joins with Array Fails Only With Storage Plugins

Hitting a bit of a wall with Apache Drill, when we query the following where the JSON is selected from a string using convertFromJSON, the query works(if you paste this into a Query window on drill it will work):
SELECT
t_items.item['secName'] as SecurityName
FROM
--dfs.tmp.`4.json` a,
( Select convert_fromjson('{
"data":{
"RefAccountAll": [
{
"valuations":[
{
"securityValuations": [{"secName":"abc"},{"secName":"def"}]
}]
}]
}
}') as a) t,
LATERAL
( SELECT c1.v.valuations as vals1 FROM
UNNEST
(t.a.data.RefAccountAll) c1(v)
) t_orders
,
LATERAL
(SELECT * FROM UNNEST(t_orders.vals1.securityValuations) _items(item) ) t_items
If I perform the same query but with the same JSON in a file (dfs.tmp.4.json), Apache Drill SQL query returns the following error:
org.apache.drill.common.exceptions.UserRemoteException: SYSTEM ERROR: UnsupportedOperationException: Unable to get new vector for minor type [LATE] and mode [OPTIONAL]
I can run other queries no problem (with the JSON in a file) but only hit this when the JSON is in a file. In the case where it blows up "c1.v.valuations" is coming up as [], but when I run it with JSON inline right in the query
"c1.v.valuations" has a nice value.
Any ideas or assistance here? You help would be so appreciated!
Thanks,
Ron
What's happening here is that Drill seems to be using different reader settings for the ConvertFROMJSON function than reading the raw JSON.
I'm wondering however, if there might be a better way of querying this data using Drill's native nested functions rather than the JOINS? Do you have a small sample file you could share?

MySql JSON Schema

I have a table in MySql somewhat like this:
create table json_docs (
id int auto_increment primary_key,
doc json not null
)
I also have a json schema that this doc column obeys.
{
"$id": "https://my.org/namespace/doc.schema.json",
"type": "object",
"properties": {...}
}
Is there a way to enforce that schema in MySql during an insert or update?
insert into json_docs (doc) values ('{...}')
I am also using PHP Laravel. If there is a way to do this in the Model layer of Laravel I would also be interested.
Thanks in advance for your help!
MySQL does have json validation support.
https://dev.mysql.com/doc/refman/8.0/en/json-validation-functions.html
MySQL does not have any feature built-in to validate JSON documents against a schema.
Update: This feature now exists in 8.0.17, but prior to that version, the following answer still applies:
You would have to validate your document in your app, independently from inserting it into a database.
See https://github.com/justinrainbow/json-schema for an open-source JSON validator in PHP.

Postgres 10, select from json object containing json array of objects

In the database I have text field contains json with the structure:
"Limits":{
"fields":[
{
"key":"DAILY_LIMIT",
"value":"1559",
"lastModified":1543857829148,
},
{
"key":"MONTHLY_LIMIT",
"value":"25590",
"lastModified":1543857829148,
}
]
}
I need to check if daily_limit exists. It's easy to do with LIKE %DAILY_LIMIT% but performance is not so good and also I won't have access to value (right now I don't need it but maybe in future, it'll be needed). There is an option to check if this key exists without killing the db? I tried with 'Limits'->'fields'-> but I don't know what should be next... And it must be done by query, I cant pass object to backend and then check it
demo: db<>fiddle
If you want to do it the JSON way this could be a solution:
WITH data AS (
SELECT 'somedata' as somedata, '{"Limits":{"fields":[{"key":"DAILY_LIMITS","value":"1559","lastModified":1543857829148},{"key":"MONTHLY_LIMIT","value":"25590","lastModified":1543857829148}]}}'::jsonb as data
)
SELECT
d.*
FROM data d, jsonb_array_elements(data -> 'Limits' -> 'fields')
WHERE value ->> 'key' = 'DAILY_LIMITS'
jsonb_array_elements expands the array into one row each element. In the next step you are able to check the key's value.
But the demo shows, that a simple LIKE would be much faster as #404 mentioned correctly (have a look at the costs of both examples.)

Have MySQL return JSON keys which themselves contain certain values

The problem I am trying to solve is to have a MySQL query return the Keys within a JSON that has the value "stage":"Functioning". I've been trying to work this problem out for a while now but can't find a solution.
It's worth adding as well that there will be several JSONs within the database table.
One of the JSONs is as follows:
{
"1493510400":{
"stage":"Resting",
"dateAltered":"true"
},
"1508716800":{
"stage":"Functioning",
"dateAltered":"true"
},
"1522713600":{
"stage":"Functioning",
"dateAltered":"true",
"stageAltered":"true"
},
"1537315200":{
"stage":"Functioning",
"stageAltered":"true"
},
"1551916800":{
"stage":"Resting",
"stageAltered":"true"
},
"1566518400":{
"stage":"Resting",
"stageAltered":"true"
},
"1581120000":{
"stage":"Functioning"
},
"1595721600":{
"stage":"Resting"
}
}
Each level has a timestamp as its key. Within each level, there will always be a value for 'stage'. These are only ever going to be Resting or Functioning. From here, I need to create a query that will return all the keys (timestamps) that have a value "stage":"Functioning".
I've got SELECT JSON_KEYS(field_value) working fine and it returns an array of the timestamps but when I try adding on some WHERE statements, it fails to return anything.
Some of the queries I've tried are:
SELECT JSON_KEYS(field_value) WHERE JSON_EXTRACT(field_value, '$*.stage') = 'Functioning'
SELECT JSON_KEYS(field_value) WHERE JSON_CONTAINS(field_value, '{"stage":"Functioning"}', '$.stage')
I know I'm probably being an idiot here so apologies if this feels like a waste of time to people but I'm totally stumped right now.
Is what I'm trying to accomplish even possible within MySQL?
My current version of MySQL is 5.7.22
Thanks
I'm afraid your version doesn't support that functionality. If you can upgrade to MySQL 8.0.11, you can use JSON_TABLE, JSON_SEARCH or something similar, depending on your individual case (honestly no clue what exactly you want to achieve based on your post).

Parse JSON in MySQL

I need help on how to parse JSON data in MySQL.
I can parse a column named config containing data such as:
{"encounterId":"f45bf821-98e1-4496-82ef-047971e168cb","providerId":"38001853-d2e1-4361-9fff-cfca1aedf406","patientId":"f4d04edb-652f-427c-ac25-6fecbda2a0aa","obs":[{"conceptId":"4e903795-ad79-48fc-851e-9e67c9628e6b","value":0.0},{"conceptId":"5300c3e4-3b53-4a0b-874b-3060d18cec9b","value":"Q"},{"conceptId":"dded4485-6160-4791-a13d-16c87f5004dc","value":"000019"},{"conceptId":"4e503f63-caa0-419a-8670-112441d228da","value":"girl"}],"dateCreated":"Dec 5, 2012 9:39:01 AM","formId":"ETAT","locationId":"","created":1354693141902}
by using
select common_schema.get_option(be.config,'encounterid') AS eid
, common_schema.get_option(be.config,'providerid') AS gender
, common_schema.get_option(be.config,'patientid') AS pid
from bencounter be
to get what I need.
However, I am unable to get the data for 'obs' which is several 'rows' of the fields conceptid and value.
Further more any reference to a field after the 'set' of obs returns a null
select common_schema.get_option(be.config,'encounterid') AS eid
, common_schema.get_option(be.config,'providerid') AS gender
, common_schema.get_option(be.config,'patientid') AS pid
, common_schema.get_option(be.config,'formId') AS formid -- THIS RETURNS NULL
from bencounter be
Can some one please help me figure this out.
I would like to solve this directly in MySQL...
Clemens
Here's a solution in MySQL 5.7 syntax:
select be.config->'$.encounterId' AS eid
, be.config->'$.providerId' AS gender
, be.config->'$.patientId' AS pid
, be.config->'$.formId' AS formid
from bencounter be \G
Output:
*************************** 1. row ***************************
eid: "f45bf821-98e1-4496-82ef-047971e168cb"
gender: "38001853-d2e1-4361-9fff-cfca1aedf406"
pid: "f4d04edb-652f-427c-ac25-6fecbda2a0aa"
formid: "ETAT"
Remember that field keys in JSON are case-sensitive. For example, 'formId' is not the same as 'formid'.
It appears you are using https://common-schema.googlecode.com/svn/trunk/common_schema/doc/html/get_option.html. It specifies that subdictionaries are not supported, which I think is your problem here.
Mysql is not a great tool for parsing JSON.
I think there are some efforts for future versions like 5.7 to start including some support for JSON (see http://blog.ulf-wendel.de/2014/mysql-5-7-http-plugin-mysql/).
If you are on an earlier version now you might try using UDFs like http://www.slideshare.net/mobile/SvetaSmirnova/mysql-json-functions
HTH
Either you could use a cumbersome MySQL UDF for parsing JSON for MySQL like for example https://github.com/ChrisCinelli/mysql_json
...but a better way would be to pull out the JSON and parse it in your app, and perhaps convert the data to a more suited schema for your intentions.