How to retrieve multiple data from jsonb column in postgres? - json

In PostgreSQL database I have a json column called json. Data inside look like below:
{
"Version": "0.0.0.1",
"Items": [
{
"Id": "40000000-0000-0000-0000-000000141146",
"Name": "apple",
"Score": 64,
"Value": 1430000
},
{
"Id": "40000000-0000-0000-0000-000000141147",
"Name": "grapefruit",
"Score": 58,
"Value": 1190000
},
{
"Id": "40000000-0000-0000-0000-000000141148",
"Name": "mango",
"Score": 41,
"Value": 170000
}
]
}
What I would like to do is retrieving all Score data from Items elements.
I was trying to use SQL code:
select
substring(json ->> 'Items' from '"Score": (\d*),') as score
from vegetables;
However that returns just the score from first element instead of 3. I was trying to use '\g' flag which supposed to find all results globally, but the code was not working.
Could anyone advise how to do that properly? Thanks in advance!

Considering that the data type of json field is jsonb then no need to use substring or regex, simply lateral join with jsonb_array_elements will do the required things for you. Try below query.
select x->>'Score' "Score" from vegetables
cross join lateral jsonb_array_elements(json->'Items') x
DEMO

Related

Use JSON file in postgresql database

I have a table in a postgresql database with one field with json format.
It's look like this :
[
{
"transition": "transition1",
"from": "step1",
"to": "step2",
"date": {
"date": "2021-01-30 15:34:06.840859"
}
},
{
"transition": "transition2",
"from": "step2",
"to": "step3",
"date": {
"date": "2021-01-30 16:52:00.412208"
}
}
]
I want to have a new column with the date of transition1.
I tried a lot of things but I can't figure out how to extract this date, I can't use the index because the number of transition is not fixed, some user could have 3 and other more than 10.
You need to iterate over all array elements to find the correct one:
select (select (item -> 'date' ->> 'date')::timestamp
from jsonb_array_elements(jsonb_column) as x(item)
where item ->> 'transition' = 'transition1') as transition_date
from the_table
;
If you column is defined as json rather than jsonb (which it should be) you need to use json_array_elements() instead.

Retrieve specific value from a JSON blob in MS SQL Server, using a property value?

In my DB I have a column storing JSON. The JSON looks like this:
{
"views": [
{
"id": "1",
"sections": [
{
"id": "1",
"isToggleActive": false,
"components": [
{
"id": "1",
"values": [
"02/24/2021"
]
},
{
"id": "2",
"values": []
},
{
"id": "3",
"values": [
"5393",
"02/26/2021 - Weekly"
]
},
{
"id": "5",
"values": [
""
]
}
]
}
]
}
]
}
I want to create a migration script that will extract a value from this JSON and store them in its own column.
In the JSON above, in that components array, I want to extract the second value from the component with an ID of "3" (among other things, but this is a good example). So, I want to extract the value "02/26/2021 - Weekly" to store in its own column.
I was looking at the JSON_VALUE docs, but I only see examples for specifing indexes for the json properties. I can't figure out what kind of json path I'd need. Is this even possible to do with JSON_VALUE?
EDIT: To clarify, the views and sections components can have static array indexes, so I can use views[0].sections[0] for them. Currently, this is all I have with my SQL query:
SELECT
*
FROM OPENJSON(#jsonInfo, '$.views[0].sections[0]')
You need to use OPENJSON to break out the inner array, then filter it with a WHERE and finally select the correct value with JSON_VALUE
SELECT
JSON_VALUE(components.value, '$.values[1]')
FROM OPENJSON (#jsonInfo, '$.views[0].sections[0].components') components
WHERE JSON_VALUE(components.value, '$.id') = '3'

Stream Analytics: performing a JOIN on events and ref. data in JSON

I'd like to perform a JOIN query on incoming JSON events and JSON reference data in Azure Stream Analytics.
The JSON events look like the following:
{"devicename":"12345","value":25}
The JSON Reference data (simplified) looks like the following:
{
"Id": "configuration",
"Sites": [{
"Id": "b83939b5-6502-4140-b807-205162ac4939",
"Name": "site1",
"Location": {
"Latitude": 5.000,
"Longitude": 5.000
},
"Lines": [{
"Id": "e707a451-948a-498e-80de-d61bc448a5ef",
"Name": "line1",
"Sections": [{
"Id": "d17d762c-4291-4912-9dcf-72113c9f0b4b",
"Name": "section1",
"Sensors": [{
"Id": "S1_PL1_LS1_M1_device_001",
"Name": "sensor1",
"ExpectedAVG": 55,
"ExpectedMIN": 35,
"ExpectedMAX": 75,
"TypeOfSensor": "Humidity"
}, {
"Id": "S1_PL1_LS1_M1_device_002",
"Name": "sensor2",
"ExpectedAVG": 105,
"ExpectedMIN": 90,
"ExpectedMAX": 118,
"TypeOfSensor": "Temperature"
}]
}]
}]
}]
}
Now I'd like to perform a JOIN on the incoming device data and the reference data.
SELECT
i.devicename as pk,
i.value as rk,
system.timestamp as time,
r.Sites.Lines.Sections.Sensors.Temperature as Temperature,
r.Sites.Lines.Sections.Sensors.Humidity as Humidity
INTO
output
FROM
IoTHubStream i
INNER JOIN
Reference r ON r.Sites.Lines.Sections.Sensors.Id = i.devicename
Now how can this be done? The problem is that the reference data can change and I would like to handle this dynamically.
I'm thinking about using a WHERE statement but I don't know how this could look like, some advice/help is really welcome.
Thanks in advance!
You can access the array elements using GetArrayElements described in this page https://msdn.microsoft.com/en-us/library/azure/mt298451.aspx
If your data changes make it impossible to use GetArrayElements, please share details about how it changes.

MySQL regexp search JSON array

I am storing json data to one of the fields in a table and I am having trouble using REGEXP to return the correct entry
Basically, it matches other attributes in the JSON object, that it should not
Sample JSON
{
"data": {
"en": {
"containers": [
{
"id": 1441530944931,
"template": "12",
"columns": {
"column1": [
"144",
"145",
"148"
],
"column2":[
"135",
"148",
"234"
]
}
}
],
"left": "152",
"right": "151"
},
}
}
Now, I would like to search the columns array against a specific value (ie 148)
Right now I have the below query
WHERE (w.`_attrs` REGEXP '"column[0-9]":.*\\[.*"148".*\\]'
which works just fine
However, if I change the value from 148 to 152 or 151, it also works
For some reason the query matches the attribute left and right as well, but this is not desirable
Any help?
Thanks
Or... Switch to MariaDB 10 and index the components of the JSON.

Access deeper elements of a JSON using postgresql 9.4

I want to be able to access deeper elements stored in a json in the field json, stored in a postgresql database. For example, I would like to be able to access the elements that traverse the path states->events->time from the json provided below. Here is the postgreSQL query I'm using:
SELECT
data#>> '{userId}' as user,
data#>> '{region}' as region,
data#>>'{priorTimeSpentInApp}' as priotTimeSpentInApp,
data#>>'{userAttributes, "Total Friends"}' as totalFriends
from game_json
WHERE game_name LIKE 'myNewGame'
LIMIT 1000
and here is an example record from the json field
{
"region": "oh",
"deviceModel": "inHouseDevice",
"states": [
{
"events": [
{
"time": 1430247045.176,
"name": "Session Start",
"value": 0,
"parameters": {
"Balance": "40"
},
"info": ""
},
{
"time": 1430247293.501,
"name": "Mission1",
"value": 1,
"parameters": {
"Result": "Win ",
"Replay": "no",
"Attempt Number": "1"
},
"info": ""
}
]
}
],
"priorTimeSpentInApp": 28989.41467999999,
"country": "CA",
"city": "vancouver",
"isDeveloper": true,
"time": 1430247044.414,
"duration": 411.53,
"timezone": "America/Cleveland",
"priorSessions": 47,
"experiments": [],
"systemVersion": "3.8.1",
"appVersion": "14312",
"userId": "ef617d7ad4c6982e2cb7f6902801eb8a",
"isSession": true,
"firstRun": 1429572011.15,
"priorEvents": 69,
"userAttributes": {
"Total Friends": "0",
"Device Type": "Tablet",
"Social Connection": "None",
"Item Slots Owned": "12",
"Total Levels Played": "0",
"Retention Cohort": "Day 0",
"Player Progression": "0",
"Characters Owned": "1"
},
"deviceId": "ef617d7ad4c6982e2cb7f6902801eb8a"
}
That SQL query works, except that it doesn't give me any return values for totalFriends (e.g. data#>>'{userAttributes, "Total Friends"}' as totalFriends). I assume that part of the problem is that events falls within a square bracket (I don't know what that indicates in the json format) as opposed to a curly brace, but I'm also unable to extract values from the userAttributes key.
I would appreciate it if anyone could help me.
I'm sorry if this question has been asked elsewhere. I'm so new to postgresql and even json that I'm having trouble coming up with the proper terminology to find the answers to this (and related) questions.
You should definitely familiarize yourself with the basics of json
and json functions and operators in Postgres.
In the second source pay attention to the operators -> and ->>.
General rule: use -> to get a json object, ->> to get a json value as text.
Using these operators you can rewrite your query in the way which returns correct value of 'Total Friends':
select
data->>'userId' as user,
data->>'region' as region,
data->>'priorTimeSpentInApp' as priotTimeSpentInApp,
data->'userAttributes'->>'Total Friends' as totalFriends
from game_json
where game_name like 'myNewGame';
Json objects in square brackets are elements of a json array.
Json arrays may have many elements.
The elements are accessed by an index.
Json arrays are indexed from 0 (the first element of an array has an index 0).
Example:
select
data->'states'->0->'events'->1->>'name'
from game_json
where game_name like 'myNewGame';
-- returns "Mission1"
select
data->'states'->0->'events'->1->>'name'
from game_json
where game_name like 'myNewGame';
This did help me