Snowflake - Lateral flatten: Nested Objects - snowflake-cloud-data-platform

This is a JSON nested object in one of the columns in snowflake table.
I wanted to pull the "id" which is part of statusCategory object.
Need help in deriving this.
"status":
{
"description": "",
"id": "10147",
"name": "Done",
"statusCategory":
{
"colorName": "green",
"id": 3,
"key": "done",
"name": "Done",
}
}
Tried the below snowflake query.
SELECT a1.value::varchar as Derivedstatus
,a2.value::varchar as Derivedid
FROM SnowflakeTable A
,lateral flatten(input => parse_json(FULL_PAYLOAD):fields:status:statusCategory) as a1
,lateral flatten(input => a1.value:"id") as a2
But does not give any output.

So for starters, the JSON you have is invalid, it needs one more layer of brackets:
{
"status":
{
"description": "",
"id": "10147",
"name": "Done",
"statusCategory":
{
"colorName": "green",
"id": 3,
"key": "done",
"name": "Done",
}
}
}
then how you use it, it seems to think there should be a fields: so that would require another layer:
{
"fields": {
"status":
{
"description": "",
"id": "10147",
"name": "Done",
"statusCategory":
{
"colorName": "green",
"id": 3,
"key": "done",
"name": "Done",
}
}
}
}
thus:
with SnowflakeTable(FULL_PAYLOAD) as (
select parse_json('{"fields":
{
"status":
{
"description": "",
"id": "10147",
"name": "Done",
"statusCategory":
{
"colorName": "green",
"id": 3,
"key": "done",
"name": "Done",
}
}}}')
)
SELECT
a.*
,FULL_PAYLOAD:fields
,FULL_PAYLOAD:fields:status
,FULL_PAYLOAD:fields:status:statusCategory
FROM SnowflakeTable A
gives:
{ "colorName": "green", "id": 3, "key": "done", "name": "Done" }
for the last part..
at which point your first flatten:
SELECT
a1.value::varchar as Derivedstatus
FROM SnowflakeTable A
,lateral flatten(input => FULL_PAYLOAD:fields:status:statusCategory) as a1
gives:
DERIVEDSTATUS
green
3
done
Done
what you are trying to do with the second layer of flatten is not clear.. as there are no more nested items to flatten..
So this part will need more explanation of what values you are hoping to exact.
Guess 1:
If you only have one status category, per status: you can just directly access the values:
SELECT
a.FULL_PAYLOAD:fields:status:statusCategory:key::text as key
,a.FULL_PAYLOAD:fields:status:statusCategory:id::text as Derivedid
,a.FULL_PAYLOAD:fields:status:statusCategory:name::text as DerivedStatus
FROM SnowflakeTable AS a
gives:
KEY
DERIVEDID
DERIVEDSTATUS
done
3
Done

Related

Formatting data in table using react-bootstrap

I have a grouped object like below:
{
"L": [
{
"key": "0",
"name": "Bran"
},
{
"key": "6",
"name": "Janet"
},
{
"key": "18",
"name": "David"
},
{
"key": "20",
"name": "Sandy"
}
],
"P": [
{
"key": "5",
"name": "Emma"
},
{
"key": "4",
"name": "Helen"
}
],
"C": [
{
"key": "2",
"name": "Arthur"
}
]
}
The above object is dynamic with any no. of keys and values.
I would like to use react-bootstrap table to format the above data in a table like this:
L
P
C
Bran
Emma
Arthur
Janet
Helen
David
Sandy
If it can be easily achieved with react-bootstrap-table2, please suggest that too.
How would I achieve this?
Any help is appreciated. Thanks!

needs to added json parent array name to every sub array

Flutter / Dart Question
This is the array which I have , In the Accessories list it contains brand name("samsung"), I need to added the brand name to all the sub array.
you can see the second code space in the sub array of Brand name key it contains brand name of the parent key
{
"Accessories": [
{"id": 1,
"brand": "samsung",
"parentId": null,
"children": [
{
"id": 4,
"name": "Ace",
"parentId": 1
},
{
"id": 5,
"name": "note",
"parentId": 1
},
{
"id": 6,
"name": "galaxy",
"parentId": 1
}
]
},
{"id": 2,
"name": "Asus",
"parentId": null,
"children": [
{
"id": 7,
"name": "gaming",
"parentId": 2
},
{
"id": 8,
"name": "office",
"parentId": 2
}
]
},
]
}
what I expecting result is below
{
"phones": [
{
"id": 1,
"brand": "samsung",
"parentId": null,
"children": [
{
"id": 4,
"name": "Ace",
*"brand": "samsung",*
"parentId": 1
},
{
"id": 5,
"name": "note",
*"brand": "samsung",*
"parentId": 1
},
{
"id": 6,
"name": "galaxy",
*"brand": "samsung",*
"parentId": 1
}
]
},
{
"id": 2,
"name": "Asus",
"parentId": null,
"children": [
{
"id": 7,
"name": "gaming",
*"name": "Asus",*
"parentId": 2
},
{
"id": 8,
"name": "office",
*"name": "Asus",*
"parentId": 2
}
]
},
]
}
please help me to resolve the question .
..............................................................................................................................
Assuming you are not using any class to encode and decode json and you just want to get from the first json string to the second json string:
Map<String, dynamic> decodedMap = json.decode(accessoriesJson);
final List accessories = decodedMap['Accessories'];
final List result = accessories.map((a) {
return {
...a,
'children': (a['children'] as List)
.map((c) => ({...c, 'parent': a['brand']}))
.toList(),
};
}).toList();
final resultJson = json.encode({
'phones': result,
});
Note: I assumed the name of the parent on the first json is called brand (Like in the samsung example). Although in the Asus example it's called name.
You can create json decoder/encoder class with https://app.quicktype.io/
I used the same to convert the json to Accessories type.
After that you can use the forEach two times to update the existing array without creating a new one.
Like this
var list = Accessories.fromMap(json);
print(list.accessories);
list.accessories!.forEach((e) {
var brand = e.brand;
if (brand != null) {
e.children?.forEach((element) {
element.brand = brand;
});
}
});
print(list.toMap());
I am only using "brand" because
You should keep your property name same if using array.
Using "name" in parent will add property "name" in child. Which is wrong because there is already a property named "name" in child. So it will replace the child name.
Working example
https://dartpad.dev/?id=a7f4a869d02db3b929e3814db28fcbe1&null_safety=true
I had to make changes for null handling in type class as I don't know what will be the optional in this array. So I made everything optional.

In Azure Search how can I filter records that have tags with IDs matching any in a list

Given the following search index document schema:
{
"value": [
{
"Id": "abc",
"Name": "Some name",
"Tags": [
{
"Id": "123",
"Name": "Tag123"
},
{
"Id": "456",
"Name": "Tag456"
}
]
},
{
"Id": "xyz",
"Name": "Some name",
"Tags": [
{
"Id": "123",
"Name": "Tag123"
},
{
"Id": "789",
"Name": "Tag789"
}
]
},
]
}
What is the correct syntax for an OData query that will return all records with any Tag/Ids that are contained in input list?
The closest I have got is:
Tags/any(object: object/Id search.in ('123,456,789'))

Avoid using arrays (and [0]) in multidimensional JSON object

I'm storing data in a JSON file and need different objects/arrays. So far I am using the following structure:
data= [
{
"savedRuns": [
{
"id": 1,
"name": "Run 1"
},
{
"id": 2,
"name": "Run 2"
},
{
"id": 3,
"name": "Run 3"
}
]
},
{
"groups": [
{
"id": 1,
"name": "g1"
},
{
"id": 2,
"name": "g2"
},
{
"id": 3,
"name": "g3"
}
]
},
{
"locations": [
{
"id": 1,
"name": "home"
},
{
"id": 2,
"name": "work"
},
{
"id": 3,
"name": "school"
}
]
}
]
I would like to access the data in the file in an easy way, for instance:
console.log(data.savedRuns)
console.log(data.locations)
Unfortunately this returns undefined and the only way to access the data is:
console.log(data[0].savedRuns);
console.log(data[2].locations);
Since I don't necessarily know the position of the object, I would like to avoid that. If there a way around this, or a different structure to adopt for my file?
Link to JSFiddle
You have each attribute in a separate object, stored in an array. Get rid of the outer array and store the attributes in one object, then use data.savedRuns.
Thanks to Marks answer I could get the right syntax. Posting below in case of interest to others.
data = {
"savedRuns": [{
"id": 1,
"name": "Run 1"
},
{
"id": 2,
"name": "Run 2"
},
{
"id": 3,
"name": "Run 3"
}
],
"groups": [{
"id": 1,
"name": "g1"
},
{
"id": 2,
"name": "g2"
},
{
"id": 3,
"name": "g3"
}
],
"locations": [{
"id": 1,
"name": "home"
},
{
"id": 2,
"name": "work"
},
{
"id": 3,
"name": "school"
}
]
}

Add array at specific index/position in jsonb Postgresql field

I'm wondering if there's a way to append array to a specific index/position in an jsonb array in Postgresql 9.6?
Let's imagine that my code below is my json:
{
"date": "2018-02-12",
"author": "devoplex",
"block": [
{ "color": "#C70039", "title": "Fruit" },
{ "color": "#DAF7A6", "title": "Vegetable" },
{ "color": "#DAF7A6", "title": "Meat" }
]
}
I want to append this object in my "block" array:
{ "color": "#581845", "title": "Candy" }
But I want this object to become the third index/position without replacing anything. So finally I can have this result:
{
"date": "2018-02-12",
"author": "devoplex",
"block": [
{ "color": "#C70039", "title": "Fruit" }, <---- Initial line
{ "color": "#DAF7A6", "title": "Vegetable" }, <---- Initial line
{ "color": "#581845", "title": "Candy" }, <---- New line
{ "color": "#DAF7A6", "title": "Meat" } <---- Initial line
]
}
This example in not my actual code but it's the same issue. This is for the construction of a form, so it need to be in a specific order or else it won't make any sense. Thanks you.
an ugly wheel, but nothing smarter comes fast:
with c(jb) as (values('{
"date": "2018-02-12",
"author": "devoplex",
"block": [
{ "color": "#C70039", "title": "Fruit" },
{ "color": "#DAF7A6", "title": "Vegetable" },
{ "color": "#DAF7A6", "title": "Meat" }
]
}'::jsonb))
, m as (select jb,e,case when o <3 then o else o+1 end o from c, jsonb_array_elements(jb->'block') with ordinality t(e,o) union all select jb, '{ "color": "#581845", "title": "Candy" }',3 from c)
, n as (select distinct jb,jsonb_agg(e) over (order by o) a from m)
select jsonb_pretty(jsonb_set(jb,'{block}',a)) from n order by length(a::text) desc limit 1;
jsonb_pretty
----------------------------------
{ +
"date": "2018-02-12", +
"block": [ +
{ +
"color": "#C70039", +
"title": "Fruit" +
}, +
{ +
"color": "#DAF7A6", +
"title": "Vegetable"+
}, +
{ +
"color": "#581845", +
"title": "Candy" +
}, +
{ +
"color": "#DAF7A6", +
"title": "Meat" +
} +
], +
"author": "devoplex" +
}
of course you should replace 3 with other digit if you want it in other index... http://dbfiddle.uk/?rdbms=postgres_10&fiddle=ccef24ef615b30eec07be9d1be5a1f8d here's example with index taken out of main query to ind CTE

Resources