How to parse JSON array data in Oracle APEX - json

I have following JSON output.I need to parse the data in to a table .Please help me the code.
{
"type": "Campaign",
"currentStatus": "Active",
"id": "206",
"createdAt": "1488438112",
"createdBy": "370",
"depth": "complete",
"folderId": "1428",
"name": "Car Loan",
"elements": [
{
"type": "CampaignAddToProgramBuilderAction",
"id": "1197",
"name": "Create Lead",
"memberCount": "0",
},
}
],
"isReadOnly": "false",
"runAsUserId": "372",
"actualCost": "2500.00",
"budgetedCost": "0.00",
"campaignCategory": "contact",
"campaignType": "GB",
"crmId": "",
"endAt": "1496289599",
"fieldValues": [
{
"type": "FieldValue",
"id": "8",
"value": "test"
},
{
"type": "FieldValue",
"id": "9",
"value": "APAC"
},
{
"type": "FieldValue",
"id": "11",
"value": ""
},
{
"type": "FieldValue",
"id": "12",
"value": "Direct Mail Campaigns"
},
{
"type": "FieldValue",
"id": "13",
"value": ""
}
],
"firstActivation": "1488439250",
"isEmailMarketingCampaign": "false",
"isIncludedInROI": "true",
}
I have to load the all the fields in to a table.following code is loading the data without nested fields,Please help to add "actual Cost" and field values(type,id,value)in below code.
declare
l_ws_response_clob CLOB;
l_ws_url VARCHAR2(500) := 'your URL';--above given the out put of JSON
l_list json_list;
l_obj json;
l_col1 VARCHAR2(100);
l_col2 VARCHAR2(100);
l_col3 VARCHAR2(100);
l_col4 VARCHAR2(100);
l_col5 VARCHAR2(100);
l_col6 VARCHAR2(100);
l_col7 VARCHAR2(100);
l_col8 VARCHAR2(100);
begin
--get JSON
apex_web_service.g_request_headers(1).name := 'Accept';
apex_web_service.g_request_headers(1).value := 'application/json; charset=utf-8';
apex_web_service.g_request_headers(2).name := 'Content-Type';
apex_web_service.g_request_headers(2).value := 'application/json; charset=utf-8';
l_ws_response_clob := apex_web_service.make_rest_request(
p_url => l_ws_url,
p_username => 'TEST',
p_password => 'TEST',
p_http_method => 'GET'
);
l_obj := json(l_ws_response_clob);
l_list := json_list(l_obj.get('elements'));
for i in 1..l_list.count LOOP
l_col1 := json_ext.get_string(json(l_list.get(i)),'type');
l_col2 := json_ext.get_string(json(l_list.get(i)),'currentStatus');
l_col3 := json_ext.get_string(json(l_list.get(i)),'folderId');
l_col4 := json_ext.get_string(json(l_list.get(i)),'name');
l_col5 := json_ext.get_string(json(l_list.get(i)),'id');
l_col6 := json_ext.get_string(json(l_list.get(i)),'createdAt');
l_col7 := json_ext.get_string(json(l_list.get(i)),'createdBy');
l_col8 := json_ext.get_string(json(l_list.get(i)),'isEmailMarketingCampaign');
--Actual cost and field values(type,id,value) needs to be added here which are in array list.Please help code here
INSERT INTO CAMPAIGN_TEST(RECORD_NUM,TYPE,CURRENT_STATUS,FOLDERID,NAME,ID,CREATEDAT,CREATEDBY,ISEMAILMARKETINGCAMPAIGN,) VALUES (i,l_col1,l_col2,l_col3,l_col4,l_col5,l_col6,l_col7,l_col8);
end LOOP;
end;

That's a pretty bad JSON you are dealing with there. Dangling commas (not allowed) and numbers stored as text instead of being delivered as numbers.
But that aside this is how you parse the data
declare
l_json varchar2 (32767) := '{"type": "Campaign","currentStatus": "Active","id": "206","createdAt": "1488438112","createdBy": "370",
"depth": "complete","folderId": "1428","name": "Car Loan", "elements": [ {
"type": "CampaignAddToProgramBuilderAction",
"id": "1197",
"name": "Create Lead",
"memberCount": "0"
}],
"isReadOnly": "false","runAsUserId": "372","actualCost": "2500.00","budgetedCost": "0.00","campaignCategory": "contact","campaignType": "GB",
"crmId": "","endAt": "1496289599","fieldValues": [ { "type": "FieldValue", "id": "8", "value": "test" },
{ "type": "FieldValue", "id": "9", "value": "APAC" },
{ "type": "FieldValue", "id": "11", "value": "" },
{ "type": "FieldValue", "id": "12", "value": "Direct Mail Campaigns" },
{ "type": "FieldValue", "id": "13", "value": "" }
],
"firstActivation": "1488439250","isEmailMarketingCampaign": "false","isIncludedInROI": "true"}';
l_number number;
begin
apex_json.parse (l_json);
--actualCost
l_number := to_number (apex_json.get_varchar2 ('actualCost'), '999999999990D00', 'NLS_NUMERIC_CHARACTERS=''.,''');
dbms_output.put_line ('Actual cost: ' || l_number);
-- fieldValues
for i in 1 .. apex_json.get_count ('fieldValues') loop
dbms_output.put_line ('Item number ' || i);
dbms_output.put_line (chr (9) || ' * Type: ' || apex_json.get_varchar2 ('fieldValues[%d].type', i));
dbms_output.put_line (chr (9) || ' * Id: ' || apex_json.get_varchar2 ('fieldValues[%d].id', i));
dbms_output.put_line (chr (9) || ' * Value: ' || apex_json.get_varchar2 ('fieldValues[%d].value', i));
end loop;
end;
Which then gives the output of:
Actual cost: 2500
Item number 1
* Type: FieldValue
* Id: 8
* Value: test
Item number 2
* Type: FieldValue
* Id: 9
* Value: APAC
Item number 3
* Type: FieldValue
* Id: 11
* Value:
Item number 4
* Type: FieldValue
* Id: 12
* Value: Direct Mail Campaigns
Item number 5
* Type: FieldValue
* Id: 13
* Value:

you may base your code with following code
instead of harcoded json you can send l_obj to xmltable function
then you can use insert to table
select T1.*,T2.*
from xmltable (
'/json'
passing apex_json.to_xmltype('
{
"type": "Campaign",
"currentStatus": "Active",
"id": "206",
"createdAt": "1488438112",
"createdBy": "370",
"depth": "complete",
"folderId": "1428",
"name": "Car Loan",
"elements": [{
"type": "CampaignAddToProgramBuilderAction",
"id": "1197",
"name": "Create Lead",
"memberCount": "0"
}],
"isReadOnly": "false",
"runAsUserId": "372",
"actualCost": "2500.00",
"budgetedCost": "0.00",
"campaignCategory": "contact",
"campaignType": "GB",
"crmId": "",
"endAt": "1496289599",
"fieldValues": [{
"type": "FieldValue",
"id": "8",
"value": "test"
}, {
"type": "FieldValue",
"id": "9",
"value": "APAC"
}, {
"type": "FieldValue",
"id": "11",
"value": ""
}, {
"type": "FieldValue",
"id": "12",
"value": "Direct Mail Campaigns"
}, {
"type": "FieldValue",
"id": "13",
"value": ""
}],
"firstActivation": "1488439250",
"isEmailMarketingCampaign": "false",
"isIncludedInROI": "true"
}
')
columns
type varchar2(1000) path '/row/type',
currentStatus varchar2(1000) path '/row/currentStatus',
folderId varchar2(1000) path '/row/folderId',
name varchar2(1000) path '/row/name',
id varchar2(1000) path '/row/id',
createdAt varchar2(1000) path '/row/createdAt',
createdBy varchar2(1000) path '/row/createdBy',
isEmailMarketingCampaign varchar2(1000) path '/row/isEmailMarketingCampaign',
actualCost varchar2(1000) path '/row/actualCost' ) T1,
xmltable (
'/json/fieldValues/row'
passing apex_json.to_xmltype('
{
"type": "Campaign",
"currentStatus": "Active",
"id": "206",
"createdAt": "1488438112",
"createdBy": "370",
"depth": "complete",
"folderId": "1428",
"name": "Car Loan",
"elements": [{
"type": "CampaignAddToProgramBuilderAction",
"id": "1197",
"name": "Create Lead",
"memberCount": "0"
}],
"isReadOnly": "false",
"runAsUserId": "372",
"actualCost": "2500.00",
"budgetedCost": "0.00",
"campaignCategory": "contact",
"campaignType": "GB",
"crmId": "",
"endAt": "1496289599",
"fieldValues": [{
"type": "FieldValue",
"id": "8",
"value": "test"
}, {
"type": "FieldValue",
"id": "9",
"value": "APAC"
}, {
"type": "FieldValue",
"id": "11",
"value": ""
}, {
"type": "FieldValue",
"id": "12",
"value": "Direct Mail Campaigns"
}, {
"type": "FieldValue",
"id": "13",
"value": ""
}],
"firstActivation": "1488439250",
"isEmailMarketingCampaign": "false",
"isIncludedInROI": "true"
}
')
columns
type varchar2(1000) path '/row/type',
id varchar2(1000) path '/row/id',
value varchar2(1000) path '/row/value'
) T2;

Related

INSERT JSON One by one

I get some problem with insert json at LOOP to Oracle DB.
{
"items": [
{
"identificationMethod": "N",
"idNumber": "7779",
"bonuses": [
{
"dateFrom": "2023-01-01",
"dateTo": "2023-12-31",
"value": 500,
"currency": "PLN",
"name": "11DOD",
"kind": "1"
},
{
"dateFrom": "2023-01-01",
"dateTo": "2023-12-31",
"value": 500,
"currency": "PLN",
"name": "22DOD",
"kind": "1"
}
]
},
{
"identificationMethod": "N",
"idNumber": "7790",
"bonuses": [
{
"dateFrom": "2023-01-01",
"dateTo": "2023-12-31",
"value": 500,
"currency": "PLN",
"name": "333DOD",
"kind": "1"
},
{
"dateFrom": "2023-01-01",
"dateTo": "2023-12-31",
"value": 500,
"currency": "PLN",
"name": "444DOD",
"kind": "1"
}
]
}
]
}
What i need to do is insert first Item with 2 bonuses, next second item with another bonuses
FOR IDOD IN ( SELECT
json.*
FROM
json_table(i_body,'$.items.bonuses[*]' COLUMNS( DATE1 PATH '$.dateFrom',
DATE2 PATH '$.dateTo',
value1 PATH '$.value',
value2 PATH '$.currency',
name PATH '$.name',
kind PATH '$.kind' )) json)
LOOP
END LOOP;
The case is to replace * in '$.items.bonuses[*]' with 0 next whit 1 next 2.... etc. HOW ?!
I try to use variables but nothing work.

Count numbers in jsonata objects

can someone help me, because i am in sadness because it did not work out. Json values ​​about employees are passed to the date object, then the condition of their choice is fulfilled, if everything is true in the condition, then 1 is entered in the cnti field, if not, then nothing is entered. As a result, if two people satisfy the condition, then I display two 1 (1 and 1). How can I count the number of 1 and output their number as a result.
Below I will show you how it works.
This is json code
"schedules":[
{
"user": {
"id": 1111,
"email": "aaa#gmail.com",
"role": "user",
"profile": {
"lastName": "test",
"firstName": "test",
"fullName": "test",
"position": "salesman",
"restaurant": 1111,
"phone": "+66456464",
"trainee": null,
"__typename": "UserProfile"
},
"isActive": true,
"documents": [],
"__typename": "User"
},
"events": [
{
"userId": 1111,
"eventId": 11111111,
"type": "Shift",
"position": null,
"restaurantId": 222222,
"state": "PUBLISHED",
"__typename": "UserEvent"
},
{
"userId": 1111,
"eventId": 11111111,
"type": "Shift",
"position": null,
"restaurantId": 222222,
"state": "PUBLISHED",
"__typename": "UserEvent"
}
],
"__typename": "UserSchedule"
},
{
"user": {
"id": 1111
"email": "aaa#gmail.com",
"role": "user",
"profile": {
"lastName": "test",
"firstName": "test",
"fullName": "test",
"position": "salesman",
"restaurant": 1111,
"phone": "+66456464",
"trainee": null,
"__typename": "UserProfile"
},
"isActive": true,
"documents": [],
"__typename": "User"
},
"events": [
{
"userId": 1111,
"eventId": 11111111,
"type": "Shift",
"position": null,
"restaurantId": 222222,
"state": "PUBLISHED",
"__typename": "UserEvent"
},
{
"userId": 1111,
"eventId": 11111111,
"type": "Shift",
"position": null,
"restaurantId": 222222,
"state": "PUBLISHED",
"__typename": "UserEvent"
}
],
"__typename": "UserSchedule"
}
]
and now i show a piece of code in jsonata which handles that json
(
$selectedDate := selectedDate;
$from := $moment(from).clone().add($selectedDate, 'day');
$to := $from.clone().add(0,'day');
$dayMillis := 24 * 3600000;
$all := 1;
$dayNum := $floor($to.diff($from) / $dayMillis);
$days := [0..$dayNum].($n:=$; $from.clone().add($n,'day')).{
"dayOfMonth": format('D'),
"dayOfWeek": format('dd'),
"from": $from,
"to": $to
};
$restaurant := $query('query restaurant($id: Int!) { restaurant(id: $id) { id title address } }', {"id": restaurant}).restaurant;
$user := $query('query currentUser { currentUser { id profile { firstName lastName patronymic position } }}', {}).currentUser;
$q := 'query schedules($filter: FilterSchedulesInput) {
schedules(filter: $filter) {
user {
id
profile {
lastName
firstName
patronymic
position
}
}
events {
eventId
beginAt
endAt
type
position
details
restaurantId
state
}
}
}';
$schedules := $query($q,
{
"filter": {
"restaurant": restaurant,
"from": $from.clone().startOf('day').toISOString(),
"to": $from.clone().endOf('day').toISOString(),
"filter": null
}
}).schedules;
{
"days": $days,
"from": $from.format('DD.MM.YYYY'),
"to": $to.format('DD.MM.YYYY'),
"restaurant": $restaurant,
"userName": user.profile.lastName & ' ' & $substring($user.profile.firstName, 0, 1) & '.' & $substring($user.profile.patronymic, 0, 1) & '.',
"data": $schedules.(
$events := events[type='Смена']~>|$|{
"details": details ? $eval(details),
"hours": $round(($toMillis(endAt) - $toMillis(beginAt))/3600000 + 0.5),
"date": $substring(beginAt, 0, 10),
"all" : $all,
"position" : position,
"dateAt": beginAt,
"dateOut": endAt
},['__typename']|;
$cnti := $events.all;
$details := $events.details;
$total := $sum($append([], $events.hours));
{
"position": user.profile.position,
"det": $details,
"cnti": $cnti,
"name": user.profile.lastName & ' ' & $substring($user.profile.firstName, 0, 1) & '.' & $substring($user.profile.patronymic, 0, 1) & '.',
"total": $total,
)
};
)^(name)
};
)
in the code above i added comments that can explain you how it works. i tried to add string like $total(sum all numbers from cnti, but it didn't work)
and it is code for html document in which I output 1
<div>
<table cellpadding="0" cellspacing="0">
<tr>
<th>Проверка</th>
<th>{{#each data}}{{cnti}}{{/if}}{{/each}}</th>
</tr>
<tr>
<th>Trading point</th>
<th></th>
</tr>
</table>
</div>
that is the picture of result i got(first image)
enter image description here
that is the result i need(second image)
enter image description here

How to Append to an Array in BigQuery or: How I Learned to Handle Optional Responses in Multiple Choice Typeform Payload

Working with Typeform Surveys
Here is the survey design for question 1:
Here is the survey design for question 2:
Here is the survey design for question 3:
Response Data
I took the survey twice.
On the first submission:
(favorite color) red, blue, Other: yellow
(quest) To seek the holy grail
(another question) what is your name
On the second submission:
(favorite color) red, Other: orange
(quest) Other: something else
(another question) What... is the air-speed velocity of an unladen swallow?
Here is a sample JSON file, which I saved as option.json:
{ "event_id": "EVENT_ID_1", "event_type": "form_response", "form_response": { "submitted_at": "2022-07-12T22:51:01Z", "token": "TOKEN_1", "calculated": null, "answers": [{ "value": { "boolean": null, "file_url": null, "url": null, "phone_number": null, "email": null, "field": { "ref": "QUESTION_REF_1", "id": "QUESTION_ID_1", "type": "multiple_choice" }, "text": null, "number": null, "choices": { "labels": [{ "value": "red" }, { "value": "blue" }], "other": "yellow" }, "type": "choices", "date": null, "choice": null } }, { "value": { "boolean": null, "file_url": null, "url": null, "phone_number": null, "email": null, "field": { "ref": "QUESTION_REF_2", "id": "QUESTION_ID_2", "type": "multiple_choice" }, "text": null, "number": null, "choices": { "labels": [{ "value": "To seek the holy grail" }], "other": null }, "type": "choices", "date": null, "choice": null } }, { "value": { "boolean": null, "file_url": null, "url": null, "phone_number": null, "email": null, "field": { "ref": "QUESTION_REF_3", "id": "QUESTION_ID_3", "type": "short_text" }, "text": "what is your name", "number": null, "choices": null, "type": "text", "date": null, "choice": null } }], "form_id": "FORM_ID", "variables": [], "definition": { "id": "FORM_ID", "title": "Test Multiple Choice Other", "fields": [{ "value": { "ref": "QUESTION_REF_1", "id": "QUESTION_ID_1", "type": "multiple_choice", "title": "What is your favorite color?", "choices": [{ "value": { "id": "CHOICE_ID_1", "label": "red" } }, { "value": { "id": "CHOICE_ID_2", "label": "blue" } }], "allow_multiple_selections": "true", "allow_other_choice": "true" } }, { "value": { "ref": "QUESTION_REF_2", "id": "QUESTION_ID_2", "type": "multiple_choice", "title": "What is your quest?", "choices": [{ "value": { "id": "CHOICE_ID_3", "label": "To seek the holy grail" } }], "allow_multiple_selections": "true", "allow_other_choice": "true" } }, { "value": { "ref": "QUESTION_REF_3", "id": "QUESTION_ID_3", "type": "short_text", "title": "What else could I ask?", "choices": [], "allow_multiple_selections": null, "allow_other_choice": null } }] }, "hidden": null, "landed_at": "2022-07-12T22:49:34Z" }, "_sdc_received_at": "2022-07-12T22:51:33.248Z", "_sdc_sequence": "1657666262148", "_sdc_batched_at": "2022-07-12T22:57:17.785Z", "_sdc_table_version": "0" }
{ "event_id": "EVENT_ID_2", "event_type": "form_response", "form_response": { "submitted_at": "2022-07-12T22:53:08Z", "token": "TOKEN_2", "calculated": null, "answers": [{ "value": { "boolean": null, "file_url": null, "url": null, "phone_number": null, "email": null, "field": { "ref": "QUESTION_REF_1", "id": "QUESTION_ID_1", "type": "multiple_choice" }, "text": null, "number": null, "choices": { "labels": [{ "value": "red" }], "other": "orange" }, "type": "choices", "date": null, "choice": null } }, { "value": { "boolean": null, "file_url": null, "url": null, "phone_number": null, "email": null, "field": { "ref": "QUESTION_REF_2", "id": "QUESTION_ID_2", "type": "multiple_choice" }, "text": null, "number": null, "choices": { "labels": [], "other": "something else" }, "type": "choices", "date": null, "choice": null } }, { "value": { "boolean": null, "file_url": null, "url": null, "phone_number": null, "email": null, "field": { "ref": "QUESTION_REF_3", "id": "QUESTION_ID_3", "type": "short_text" }, "text": "What... is the air-speed velocity of an unladen swallow?", "number": null, "choices": null, "type": "text", "date": null, "choice": null } }], "form_id": "FORM_ID", "variables": [], "definition": { "id": "FORM_ID", "title": "Test Multiple Choice Other", "fields": [{ "value": { "ref": "QUESTION_REF_1", "id": "QUESTION_ID_1", "type": "multiple_choice", "title": "What is your favorite color?", "choices": [{ "value": { "id": "CHOICE_ID_1", "label": "red" } }, { "value": { "id": "CHOICE_ID_2", "label": "blue" } }], "allow_multiple_selections": "true", "allow_other_choice": "true" } }, { "value": { "ref": "QUESTION_REF_2", "id": "QUESTION_ID_2", "type": "multiple_choice", "title": "What is your quest?", "choices": [{ "value": { "id": "CHOICE_ID_3", "label": "To seek the holy grail" } }], "allow_multiple_selections": "true", "allow_other_choice": "true" } }, { "value": { "ref": "QUESTION_REF_3", "id": "QUESTION_ID_3", "type": "short_text", "title": "What else could I ask?", "choices": [], "allow_multiple_selections": null, "allow_other_choice": null } }] }, "hidden": null, "landed_at": "2022-07-12T22:51:27Z" }, "_sdc_received_at": "2022-07-12T22:53:38.604Z", "_sdc_sequence": "1657666388772", "_sdc_batched_at": "2022-07-12T22:57:17.818Z", "_sdc_table_version": "0" }
Then I created a table in BigQuery using that option.json file:
I am trying to flatten this in a way that I can easily share it with others.
sequence for multiple choice responses: one issue is that I need to keep track of how many options someone selects for each multiple choice question.
another problem is that I need to be able to handle the "other" option, which does not get saved in the same way as a regular multiple choice option.
What I have so far works fine as long as no one selects "optional" in the multiple choice types:
SELECT
tf.event_id,
a.value.field.id AS question_id,
f.value.title AS question_title,
a.value.type AS question_type,
CASE
WHEN a.value.type = 'choices' THEN c.value
WHEN a.value.type = 'text' THEN a.value.text
END AS value,
IF( a.value.type = 'choices' , choices_index+1 , 1 ) AS sequence,
COALESCE( ARRAY_LENGTH( a.value.choices.labels ) , 1 ) AS sequence_end,
FROM `<PROJECT_ID>.<DATASET_ID>.option` AS tf
LEFT JOIN UNNEST( tf.form_response.answers ) AS a
LEFT JOIN UNNEST( a.value.choices.labels ) AS c WITH OFFSET AS choices_index
INNER JOIN UNNEST( form_response.definition.fields ) f
ON a.value.field.id = f.value.id
Result:
Result in JSON:
[{
"event_id": "EVENT_ID_1",
"question_id": "QUESTION_ID_1",
"question_title": "What is your favorite color?",
"question_type": "choices",
"value": "red",
"sequence": "1",
"sequence_end": "2"
}, {
"event_id": "EVENT_ID_1",
"question_id": "QUESTION_ID_1",
"question_title": "What is your favorite color?",
"question_type": "choices",
"value": "blue",
"sequence": "2",
"sequence_end": "2"
}, {
"event_id": "EVENT_ID_1",
"question_id": "QUESTION_ID_2",
"question_title": "What is your quest?",
"question_type": "choices",
"value": "To seek the holy grail",
"sequence": "1",
"sequence_end": "1"
}, {
"event_id": "EVENT_ID_1",
"question_id": "QUESTION_ID_3",
"question_title": "What else could I ask?",
"question_type": "text",
"value": "what is your name",
"sequence": "1",
"sequence_end": "1"
}, {
"event_id": "EVENT_ID_2",
"question_id": "QUESTION_ID_1",
"question_title": "What is your favorite color?",
"question_type": "choices",
"value": "red",
"sequence": "1",
"sequence_end": "1"
}, {
"event_id": "EVENT_ID_2",
"question_id": "QUESTION_ID_2",
"question_title": "What is your quest?",
"question_type": "choices",
"value": null,
"sequence": null,
"sequence_end": "0"
}, {
"event_id": "EVENT_ID_2",
"question_id": "QUESTION_ID_3",
"question_title": "What else could I ask?",
"question_type": "text",
"value": "What... is the air-speed velocity of an unladen swallow?",
"sequence": "1",
"sequence_end": "1"
}]
I want the result to append the "optional" responses to the end of the list of the multiple-choice selections, which would mean my total query result should have 9 rows.
Specifically:
EVENT_ID_1, QUESTION_ID_1 should have 3 rows:
red (sequence: 1, sequence_end: 3)
blue (sequence: 2, sequence_end: 3)
yellow (sequence: 3, sequence_end: 3)
and
EVENT_ID_2, QUESTION_ID_1 should have 2 rows:
red (sequence: 1, sequence_end: 2)
orange (sequence: 2, sequence_end: 2)
and
EVENT_ID_3, QUESTION_ID_2 should have 1 non-null row:
something else (sequence: 1, sequence_end: 1)
I need your brilliance. Could you please help?
Basic SQL approach can be:
Find all the normal response values.
Find all the other response values.
Combine them together using union all
Below is an example from your shared data:
with titles as (
select distinct f.value.id question_id,f.value.title as question_title
from `TABLE_NAME` tf
,UNNEST( form_response.definition.fields ) f
)
,response as(
 
select tf.event_id
,a.value.field.id as question_id
,a.value.type AS question_type
,CASE
WHEN a.value.type = 'choices' THEN c.value
WHEN a.value.type = 'text' THEN a.value.text
END AS value
from `TABLE_NAME` tf
,UNNEST( tf.form_response.answers ) AS a
left join UNNEST( a.value.choices.labels ) AS c
 
)
,optionals as(
select distinct tf.event_id
,a.value.field.id as question_id
,a.value.type AS question_type
,a.value.choices.other value
from `TABLE_NAME` tf
,UNNEST( tf.form_response.answers ) AS a
where a.value.choices.other is not null
 
)
select t.question_title
,f.*
,row_number() over (partition by event_id,f.question_id,question_type ) sequence
,count(*) over (partition by event_id,f.question_id,question_type) sequence_end
from (
select * from response where value is not null
union all
select * from optionals
)f
left join titles t on f.question_id = t.question_id
order by event_id,question_id
Above is just an example, your query also works fine all you have to do is get another result set which will contain only optional value and merge both results together.
N.B Use Temp tables instead of CTE.

Firebase: JSON payload not accepted

I'm trying to push JSON from a service in to Firebase, and it's not accepting it.
I cant figure out why. JSONLint validates it as valid.
The error I get is:
error: "Invalid data; couldn't parse JSON object, array, or value."
Here's the JSON payload:
{
"app_id": "e4805b8d5a9f4032b0bb8b6d9c6726b8",
"archived": false,
"attachments": {
"form.xml": {
"content_type": "text/xml",
"length": 4500,
"url": "https://someurl.com/form.xml"
}
},
"build_id": "3c5703e20346462ebcb07a3f36d5fe9b",
"domain": "my-test",
"edited_by_user_id": null,
"edited_on": null,
"form": {
"#type": "data",
"#name": "Beneficiary Registration",
"#uiVersion": "1",
"#version": "1",
"#xmlns": "http://openrosa.org/formdesigner/123456",
"beneficiary_age": {
"beneficiary_age_num": "8",
"beneficiary_exact_age_ind": "N"
},
"beneficiary_gender_cd": "M",
"beneficiary_id": "Hhr-O6I3C5L-J3G1L",
"case": {
"#case_id": "a07972bc-1a34-4c84-90ea-91250639f2a4",
"#date_modified": "2020-03-17T20:57:26.986000Z",
"#user_id": "2275c340c48ac83b6852035b0a15b5d3",
"#xmlns": "http://someurl.org/case/transaction/v2"
},
"case_name": "Hhr-O6I3C5L-J3G1L|joel galager|Katsekera|Katsekera|Mpando|Katsekera|KE",
"existing_beneficiaries": "Jane Doe\n\nJoan Doe",
"existing_beneficiaries_label": "",
"household_information": {
"beneficiary_household_information_display": "",
"beneficiary_location_hierarchy_1": "KE",
"beneficiary_location_hierarchy_1_text": "Kenya",
"beneficiary_location_hierarchy_2": "HF0001",
"beneficiary_location_hierarchy_2_text": "Katsekera",
"beneficiary_location_hierarchy_3": "TA0001",
"beneficiary_location_hierarchy_3_text": "Mpando",
"beneficiary_location_hierarchy_4": "GHV0001",
"beneficiary_location_hierarchy_4_text": "Katsekera",
"beneficiary_location_hierarchy_5": "V0001",
"beneficiary_location_hierarchy_5_text": "Katsekera",
"correct_information": "",
"hh_first_name": "John",
"hh_full_name": "John Doe",
"hh_id_fk": "Hhr-O6I3C5L",
"hh_last_name": "Doe",
"household_information": ""
},
"meta": {
"#xmlns": "http://openrosa.org/jr/xforms",
"appVersion": "Formplayer Version: 2.47",
"app_build_version": 1,
"commcare_version": null,
"deviceID": "Formplayer",
"drift": "0",
"geo_point": null,
"instanceID": "123-321-232",
"timeEnd": "2020-03-17T20:57:26.986000Z",
"timeStart": "2020-03-17T20:57:13.958000Z",
"userID": "2275c340c48ac83b6852035b0a15b5d3",
"username": "some_username"
},
"name_group": {
"beneficiary_first_name": "joel",
"beneficiary_full_name": "joel galager",
"beneficiary_last_name": "galager"
},
"subcase_0": {
"case": {
"#case_id": "2a4bfe27-a5c3-4f3a-8540-5f8ded86db85",
"#date_modified": "2020-03-17T20:57:26.986000Z",
"#user_id": "abc123",
"#xmlns": "http://commcarehq.org/case/transaction/v2",
"create": {
"case_name": "Hhr-O6I3C5L-J3G1L|joel galager|Katsekera|Katsekera|Mpando|Katsekera|KE",
"case_type": "beneficiary_case",
"owner_id": "abc123"
},
"index": {
"parent": {
"#text": "a07972bc-1a34-4c84-90ea-91250639f2a4",
"#case_type": "household_case"
}
},
"update": {
"beneficiary_age_num": "8",
"beneficiary_exact_age_ind": "N",
"beneficiary_first_name": "joel",
"beneficiary_full_name": "joel galager",
"beneficiary_gender_cd": "M",
"beneficiary_id": "Hhr-O6I3C5L-J3G1L",
"beneficiary_last_name": "galager",
"beneficiary_location_hierarchy_1": "KE",
"beneficiary_location_hierarchy_1_text": "Kenya",
"beneficiary_location_hierarchy_2": "HF0001",
"beneficiary_location_hierarchy_2_text": "Katsekera",
"beneficiary_location_hierarchy_3": "TA0001",
"beneficiary_location_hierarchy_3_text": "Mpando",
"beneficiary_location_hierarchy_4": "GHV0001",
"beneficiary_location_hierarchy_4_text": "Katsekera",
"beneficiary_location_hierarchy_5": "V0001",
"beneficiary_location_hierarchy_5_text": "Katsekera",
"hh_id_fk": "Hhr-O6I3C5L"
}
}
}
},
"id": "d547ccea-503c-4c50-b974-38ed564ae78a",
"indexed_on": "2020-03-17T21:01:04.695654",
"initial_processing_complete": true,
"is_phone_submission": true,
"metadata": {
"appVersion": "Formplayer Version: 2.47",
"app_build_version": 1,
"commcare_version": null,
"deviceID": "Formplayer",
"drift": "0",
"geo_point": null,
"instanceID": "01010101",
"location": null,
"timeEnd": "2020-03-17T20:57:26.986000Z",
"timeStart": "2020-03-17T20:57:13.958000Z",
"userID": "2275c340c48ac83b6852035b0a15b5d3",
"username": "myusername"
},
"problem": null,
"received_on": "2020-03-17T20:57:27.179986Z",
"resource_uri": "",
"server_modified_on": "2020-03-17T20:57:27.382548Z",
"type": "data",
"uiversion": "1",
"version": "1"
}
This is probably because of #type inside form.
The # character can't be used in RTDB paths.
See How data is structured from the docs.
Keys cannot contain
.
$
#
[
]
/
ASCII control characters 0-31 or 127

Parse Complex Json Data with VB.net and Newtonsoft.Json

I'm building a windows application using vb.net to take a Json file that will be downloaded daily and parse it and enter the values into a SQL database. The only part I'm getting stuck on is being about to parse the Json data to get the values I need.
Public Sub json_parse(ByVal result_json As String)
Try
Dim json As String = result_json
Dim ser As JObject = JObject.Parse(json)
Dim data As List(Of JToken) = ser.Children().ToList
For Each item As JProperty In data
item.CreateReader()
Select Case item.Name
Case "data"
For Each msg As JObject In item.Values
MsgBox(msg.ToString)
Next
End Select
Next
Catch __unusedException1__ As Exception
'MsgBox(__unusedException1__.ToString)
End Try
End Sub
{
"data": {
"wsj_mdstrip_na,us": {
"set": 1562756496071,
"ttl": 300000,
"data": {
"id": "na,us",
"type": "wsj_mdstrip",
"data": [
{
"timeZone": "CDT",
"localTimeZoneTimestamp": "5:51 AM CDT 07/10/19",
"localTimestamp": "5:51 AM 07/10/19",
"etTimestamp": "6:51 AM ET 07/10/19",
"mdTimestamp": "2019-07-10T06:51:35-04:00",
"timestamp": "2019-07-10T05:51:35.365",
"chartingSymbol": "Future/US/XCBT/YM00",
"updatedTimestamp": "2019-07-10T07:01:36-04:00"
},
{
"deltaBarPosNeg": "deltaBar-neg",
"etTimestamp": "6:51 AM ET 07/10/19",
"chartingSymbol": "Future/US/XCME/ES00",
"pastCloses": [
{
"range": "P1Y",
"price": 2775.75
},
{
"range": "P3Y",
"price": 2145.75
}
]
}
]
}
},
"wsj_nav_na,us": {
"set": 1562754843231,
"ttl": 1800000,
"isStale": false
},
"mdc_cashprices_": {
"set": 1562756402351,
"ttl": 90000,
"data": {
"id": "{\"requestedCommodities\":\"all\",\"groupIntoMapBy\":\"type\",\"groupIntoSetsBy\":\"subType\"}",
"type": "mdc_cashprices",
"data": {
"instruments": [
{
"code": null,
"djShortName": "Gold-EnglehardFab",
"instrumentID": "511498",
"name": "Engelhard fabricated products",
"subType": "Gold, per troy oz",
"type": "Precious metals",
"ask": "-",
"bid": "-",
"last": "1500.72",
"previousDay": "1509.33",
"previousYear": "1351.58"
},
{
"code": null,
"djShortName": "Silver-EngelhrdFab",
"instrumentID": "511558",
"name": "Engelhard fabricated products",
"subType": "Silver, troy oz.",
"type": "Precious metals",
"ask": "-",
"bid": "-",
"last": "18.0600",
"previousDay": "18.0960",
"previousYear": "19.3200"
},
{
"code": null,
"djShortName": "SilverHandy&HarmB",
"instrumentID": "511560",
"name": "Handy & Harman base price",
"subType": "Silver, troy oz.",
"type": "Precious metals",
"ask": "-",
"bid": "-",
"last": "15.1070",
"previousDay": "15.0420",
"previousYear": "16.1000"
},
{
"code": null,
"djShortName": "Platinum-EngelhFab",
"instrumentID": "511554",
"name": "Platinum, Engelhard fabricated products",
"subType": "Other precious metals",
"type": "Precious metals",
"ask": "-",
"bid": "-",
"last": "912.0",
"previousDay": "914.0",
"previousYear": "946.0"
},
{
"code": null,
"djShortName": "Palladium-EngelInd",
"instrumentID": "511553",
"name": "Palladium, Engelhard industrial bullion",
"subType": "Other precious metals",
"type": "Precious metals",
"ask": "-",
"bid": "-",
"last": "1561.0",
"previousDay": "1573.0",
"previousYear": "955.0"
},
{
"code": null,
"djShortName": "Palladium-EngelFab",
"instrumentID": "511552",
"name": "Palladium, Engelhard fabricated products",
"subType": "Other precious metals",
"type": "Precious metals",
"ask": "-",
"bid": "-",
"last": "1661.0",
"previousDay": "1673.0",
"previousYear": "1055.0"
}
],
"timestamp": "7/09/19"
}
}
},
"consumer_corphat_corphat": {
"set": 1562756495973,
"ttl": 90000,
"data": {
"id": "corphat",
"type": "consumer_corphat",
"data": [
{
"ncLinks": [
{
"title": "Big Decisions",
"url": "http://www.bigdecisions.com/",
"nofollow": "false"
},
{
"title": "Business Spectator",
"url": "https://www.businessspectator.com.au/",
"nofollow": "false"
}
]
},
{
"djLinks": [
{
"title": "Barron's",
"url": "https://www.barrons.com",
"nofollow": "false"
},
{
"title": "BigCharts",
"url": "http://bigcharts.marketwatch.com",
"nofollow": "false"
}
]
}
]
},
"isStale": false
}
},
"currentState": {
"data": [
"0.0.3.0.0",
"0.0.3.1.0.0.2"
],
"components": {
"code___decoratedComponent___275181c7-8620-4df3-a008-d0cd9937db22___WSJTheme---WSJBase---WSJForms---WSJTables": {
"id": "275181c7-8620-4df3-a008-d0cd9937db22",
"decorators": [
"WSJTheme",
"WSJBase",
"WSJForms",
"WSJTables"
]
},
"code___decoratedComponent___c8882c9c-15d3-4d1f-9b0e-81b6f321365d___WSJTheme---WSJBase---WSJForms---WSJTables": {
"id": "c8882c9c-15d3-4d1f-9b0e-81b6f321365d",
"decorators": [
"WSJTheme",
"WSJBase",
"WSJForms",
"WSJTables"
]
}
}
}
}
I'm trying to get the values for "last", "previousDay" and "previousYear" from:
data > mdc_cashprices_ > data > instruments > (where djShortName = "Gold-EnglehardFab" and djShortName = "Silver-EngelhrdFab" and djShortName = "Platinum-EngelhFab" and djShortName = "Palladium-EngelFab")
I'm also trying to get the value for "timestamp" from:
data > mdc_cashprices_ > data > timestamp
In my current code I can only get to the 1st "data" tier.
Any help would be greatly appreciated.
Use something like https://jsonformatter.curiousconcept.com/ to view it more easily.
Then simply
Dim Something as JObject = JObject.Parse(<your JSON>)
Then get what you want with
Something1 = Something("data")("mdc_cashprices")("data")("data")("instruments")(0)("last") 'basically you just traverse the levels, you use the id/text for regular stuff (inside {}) and numbers for arrays (inside [])
Since it's an array you would probably want to loop it
For Each item In Something("data")("mdc_cashprices")("data")("data")("instruments")
Something2 = item("last")
Next
Btw there are some formatting issues here >>> mdc_cashprices_{\"req... <<< that _ and \ shouldn't be there"