I run a simple query that returns an output like this:
[{
"polarity": "0.0",
"magnitude": "2.0",
"score": "0.5",
"entities": [{
"name": "Taubenkot",
"type": "OTHER",
"mid": "",
"wikipediaUrl": "",
"numMentions": "1",
"avgSalience": "0.150263"
}, {
"name": "Lösung",
"type": "OTHER",
"mid": "",
"wikipediaUrl": "",
"numMentions": "1",
"avgSalience": "0.145794"
}, {
"name": "Busbahnhof",
"type": "LOCATION",
"mid": "",
"wikipediaUrl": "",
"numMentions": "1",
"avgSalience": "0.108006"
}, {
"name": "Stadt",
"type": "LOCATION",
"mid": "",
"wikipediaUrl": "",
"numMentions": "3",
"avgSalience": "0.079928"
}, {
"name": "Taubenplage",
"type": "OTHER",
"mid": "",
"wikipediaUrl": "",
"numMentions": "2",
"avgSalience": "0.072326"
}, {
"name": "Rutschgefahr",
"type": "OTHER",
"mid": "",
"wikipediaUrl": "",
"numMentions": "1",
"avgSalience": "0.070839"
},
{
"name": "Meike Böschemeyer",
"type": "PERSON",
"mid": "/g/11btlnnjgf",
"wikipediaUrl": "",
"numMentions": "1",
"avgSalience": "0.00451"
}]
}]
BigQuery automatically shows the different entity key values in separate columns. How can I query a particular key's value?
I was trying this:
select JSON_VALUE(entities, '$.type') AS type from gcnlapi limit 1
but it gives me this error
No matching signature for function JSON_VALUE for argument types: ARRAY<STRUCT<name STRING, type STRING, mid STRING, ...>>, STRING. Supported signatures: JSON_VALUE(STRING, [STRING]); JSON_VALUE(JSON, [STRING]) at [3:8]
Also tried this:
select entities.type AS type from gcnlapi limit 1
but that would give me
Cannot access field type on a value with type ARRAY<STRUCT<name STRING, type STRING, mid STRING, ...>> at [5:17]
I hope this example can help you :
SELECT
polarity,
magnitude,
score,
name,
type,
mid,
wikipediaUrl,
numMentions,
avgSalience
FROM
`your_project.your_dataset.your_table`,
UNNEST(entities)
With UNNEST you can flatten your array and get the field at root level of the table and also the fields of the array (flattened).
In this query, fields at root level are polarity, magnitude and score and others correspond to the array fields.
Related
I can't get a specific row from this JSON array.
So I want to get the object where filed 'type' is equal to 'No-Data'
Are there exist any functions in SQL to take the row or some expressions?
"metadata": { "value": "JABC" },
"force": false
"users": [
{ "id": "111", "comment": "aaa", type: "Data" },
{ "id": "222", "comment": "bbb" , type:"No-Data"},
{ "id": "333", "comment": "ccc", type:"Data" }
]
You can use a JSON path query:
select jsonb_path_query_first(the_column, '$.users[*] ? (#.type == "No-Data")')
from the_table
This assumes that the column is defined as jsonb (which it should be). If it's not you have to cast it: the_column::jsonb
Online example
I have to select data from Json like this:
[
{
"id": 10100,
"externalId": "100000035",
"name": "Test1",
"companyId": 10099,
"phone": "0738003811",
"email": "test#Test.com",
"mainAddress": {
"county": "UK",
"province": "test",
"zipCode": "01234",
"city": "test",
"street": "test",
"gln": "44,37489331;26,21941193",
"country": {
"iso2": "UK",
"iso3": "UK"
}
},
"active": false,
"main": true,
"stores": [
"Test"
],
"attributes": [
{
"attributeId": 1059,
"attributeName": "CH6 name",
"attributeExternalId": null,
"attributeValueId": 74292,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": null,
"attributePlainValue": "Unknown"
},
{
"attributeId": 1061,
"attributeName": "BD",
"attributeExternalId": null,
"attributeValueId": 81720,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": null,
"attributePlainValue": "Not assigned"
}
],
"daysSinceLastOrder": null
},
{
"id": 62606,
"externalId": "VL_LC_000190",
"name": "Test",
"companyId": 17793,
"phone": "44333424",
"email": "test#email.com",
"mainAddress": {
"firmName": "test",
"county": "test",
"province": "test",
"zipCode": "247555",
"city": "test",
"street": "test",
"gln": "44.8773851;23.9223518",
"country": {
"iso2": "RO",
"iso3": "ROU"
},
"phone": "07547063789"
},
"active": true,
"main": false,
"stores": [
"Valcea"
],
"attributes": [
{
"attributeId": 1042,
"attributeName": "Type of location",
"attributeExternalId": "TYPE_OF_DIVISION",
"attributeValueId": 34506,
"attributeValueType": "MONO_LINGUAL",
"attributeValueEid": "Small OTC (<40mp)",
"attributePlainValue": "Small OTC (<40mp)"
},
{
"attributeId": 17,
"attributeName": "Limit for payment",
"attributeExternalId": "LIMIT_FOR_PAYMENT_IN_DAYS",
"attributeValueId": 59120,
"attributeValueType": "NUMBER",
"attributeValueEid": null,
"attributePlainValue": "28"
}
],
"daysSinceLastOrder": 147
}
]
I know how to select data from simple json object using "FROM OPENJSON",
but now I have to select a
AttributeValueId, AttributeId and AttributeName, attributePlainValue and CompanyId for each Attribute. So I dont know how to select data from attributes array and then how to join to this CompanyId which is one level up.
Maybe someone knows how write this query.
As mentioned by #lptr in the comments:
You need to pass the result of one OPENJSON to another, using CROSS APPLY. You can select a whole JSON object or array as a property, by using the syntax AS JSON
select
t1.companyid,
t2.*
from openjson(#j)
with (
companyId int,
attributes nvarchar(max) as json
) as t1
cross apply openjson(t1.attributes)
with
(
attributeId int,
attributeName nvarchar(100),
attributeValueId nvarchar(100),
attributePlainValue nvarchar(100)
) as t2;
db<>fiddle
For example, you can use code like this.
f1.metaData->"$.identity.customerID" = '.$customerID.'
I have a table that holds a column called additional_info.
this column contains a JSON object that looks like that:
{
"dbSources": [{
"destIp": "10.10.10.29",
"serviceType": "PostgreSql",
"srcIp": "10.10.10.68",
"database": "xe",
"clusterMember": "",
"dbId": "PostgreSql_10.10.10.29",
"clusterName": "",
"host": "",
"dbUser": "system",
"osUser": "",
"userType": "Unknown",
"srcApp": ""
},{
"destIp": "10.10.10.29",
"serviceType": "PostgreSql",
"srcIp": "10.10.10.69",
"database": "xe1",
"clusterMember": "",
"dbId": "PostgreSql_10.10.10.29",
"clusterName": "",
"host": "",
"dbUser": "system",
"osUser": "",
"userType": "Unknown",
"srcApp": ""
}]
}
I want to extract (to select) the value of "database" where srcIp equals 10.10.10.68.
meaning I want to extract the value "xe" from the first JSON object under the JSON array called dbSources.
The only thing that I could do is
select additional_info::json ->'dbSources' as db from table
but how can I continue from there?
You can do something like that:
with query as (
select j->>'database' as db,j->>'srcIp' as src_ip from json_array_elements('{
"dbSources": [{
"destIp": "10.10.10.29",
"serviceType": "PostgreSql",
"srcIp": "10.10.10.68",
"database": "xe",
"clusterMember": "",
"dbId": "PostgreSql_10.10.10.29",
"clusterName": "",
"host": "",
"dbUser": "system",
"osUser": "",
"userType": "Unknown",
"srcApp": ""
},{
"destIp": "10.10.10.29",
"serviceType": "PostgreSql",
"srcIp": "10.10.10.69",
"database": "xe1",
"clusterMember": "",
"dbId": "PostgreSql_10.10.10.29",
"clusterName": "",
"host": "",
"dbUser": "system",
"osUser": "",
"userType": "Unknown",
"srcApp": ""
}]
}'::json->'dbSources') as j)
select db from query where src_ip = '10.10.10.68'
You can use a JSON path query:
select jsonb_path_query_first(additional_info, '$.dbSources[*] ? (#.srcIp == "10.10.10.68").database')
from the_table
This assumes the column is of type jsonb (which it should be). If it's not, you need to cast it: additional_info::jsonb
For a table with name table_name, this query will extract the value of database whose srcIp is '10.10.10.68'
SELECT obj::json#>'{database}' as db_name FROM edisondb.demo r, json_array_elements(r.some_text::json#>'{dbSources}') obj WHERE obj->>'srcIp' = '10.10.10.68';
I have a VARCHAR field like this:
[
{
"config": 0,
"type": "0
},
{
"config": x,
"type": "1"
},
{
"config": "",
"type": ""
},
{
"config": [
{
"address": {},
"category": "",
"merchant": {
"data": [
10,12,23
],
"file": 0
},
"range_id": 1,
"shop_id_info": null
}
],
"type": "new"
}
]
And I need to extract merchant data from this. Desirable output is:
10
12
23
Please advise. I keep getting Cannot cast VARCHAR to array/unnest type VARCHAR
You can try using json path $.*.config.*.merchant.data.* but if it does not work for you (as for me in Athena version, where arrays in json path are not supported well) you can cast your json to ARRAY(JSON) and do some manipultaions from there (needed to fix your JSON a little bit):
Test data:
WITH dataset AS (
SELECT * FROM (VALUES
(JSON '[
{
"config": {},
"type": "0"
},
{
"config": "x",
"type": "1"
},
{
"config": "",
"type": ""
},
{
"config": [
{
"address": {},
"category": "",
"merchant": {
"data": [
10,12,23
],
"file": 0
},
"range_id": 1,
"shop_id_info": null
}
],
"type": "new"
}
]')
) AS t (json_value))
And query:
SELECT flatten(
transform(
flatten(
transform(
CAST(json_value AS ARRAY(JSON))
, json_object -> try(CAST(json_extract(json_object, '$.config') AS ARRAY(JSON))))),
json_config -> CAST(json_extract(json_config, '$.merchant.data') as ARRAY(INTEGER))))
FROM dataset
Which will give you array of numbers:
_col0
[10, 12, 23]
And from there you can continue with unnest and so on if needed.
I have a json string containing list of data, I want to write a query to get a single value based on the condition. but it is returning list of values. please help me to write a valid query in oracle database.
My json string looks like
[
{
"Key": [
{
"obj": {
"xyz":"cdf"
},
"Info": [
{
"Code": "",
"tax": "",
"rate": "",
"taxAmount": {
"formattedAmount": "",
"Amount": ""
}
},
{
"Code": "qwer",
"tax": "ggs",
"rate": "0",
"taxAmount": {
"formattedAmount": "10.00",
"Amount": "10.00"
},
"key": "qwer"
},
{
"Code": "poiu",
"tax": "ggs",
"rate": "0",
"taxAmount": {
"formattedAmount": "20.00",
"Amount": "20.00"
},
"key": "poiu"
},
{
"coverageCode": "zxcv",
"tax": "ggs",
"rate": "0",
"taxAmount": {
"formattedAmount": "30.00",
"Amount": "30.00"
},
"key": "zxcv"
}
]
},
{
"status": "S"
}
]
}
]
I want to get formattedAmount value "10.00". Written a query like
SELECT json_query(details, '$.Info.taxAmount.formattedAmount' WITH WRAPPER)
FROM details_table where json_query(details, '$.Info.Code' WITH WRAPPER) = 'qwer';
returns no value. without where clause i'll get all the formattedAmont in list [,"10.00","20.00","30.00"]