How to create JSON Array Inside JSON object using FOR JSON SQL Server 2016 - sql-server-2016

How to create JSON Array Inside JSON object using FOR JSON SQL Server 2016 (TABLE to JSON)
Here is my query:
SELECT
m.MeetingId AS tblMeeting_MeetingId,
m.Attended AS tblMeeting_Attended,
m3.CompanyId AS tblMeetingAttendants_CompanyId,
m3.MeetingAttendantsId AS tblMeetingAttendants_AttendantNameWithTitle,
m4.UserId AS tblMeetingAttendees_UserId,
m5.BrokerId AS tblMeetingBroker_BrokerId
FROM Bv.tblMeeting m
LEFT JOIN Bv.tblMeetingAttendants m3 ON m.MeetingId = m3.MeetingId
LEFT JOIN Bv.tblMeetingAttendees m4 ON m.MeetingId = m4.MeetingId
LEFT JOIN Bv.tblMeetingBroker m5 ON m.MeetingId = m5.MeetingId
WHERE m.MeetingId = 739
FOR JSON AUTO, INCLUDE_NULL_VALUES
Above query gives me result like this:
[
{
"tblMeeting_MeetingId": 739,
"tblMeeting_Attended": false,
"tblMeeting_MeetingSubject": " Benchmark China Internet Analyst",
"m3": [
{
"tblMeetingAttendants_CompanyId": 83,
"tblMeetingAttendants_AttendantNameWithTitle": 499,
"m4": [
{
"tblMeetingAttendees_UserId": null,
"m5": [
{
"tblMeetingBroker_BrokerId": 275
}
]
}
]
},
{
"tblMeetingAttendants_CompanyId": 83,
"tblMeetingAttendants_AttendantNameWithTitle": 500,
"m4": [
{
"tblMeetingAttendees_UserId": null,
"m5": [
{
"tblMeetingBroker_BrokerId": 275
}
]
}
]
},
{
"tblMeetingAttendants_CompanyId": 83,
"tblMeetingAttendants_AttendantNameWithTitle": 501,
"m4": [
{
"tblMeetingAttendees_UserId": null,
"m5": [
{
"tblMeetingBroker_BrokerId": 275
}
]
}
]
}
]
}
]
But i want result like this
[
{
"tblMeeting_MeetingId": 739,
"tblMeeting_Attended": false,
"tblMeeting_MeetingSubject": " Benchmark China Internet Analyst",
"tblMeetingAttendants_AttendantNameWithTitle": [499,500,501],
"tblMeetingAttendees_UserId": null,
"tblMeetingBroker_BrokerId": 275
}
]
Please reply as soon as possible
Thanks in advance.

It seems like this is impossible without using string concatenation and writing your own functions. There is no magic JSON_ARRAY_AGGREGATE() function. I have been looking for one myself.
Here is a related question: SQL Server 2016 for JSON output integer array

Can use JSON_QUERY with JSON PATH to format your data into a JSON array. I sampled just your MeetingID and MeetingAttendantID columns to demonstrate the concept
Build JSON Array using JSON_QUERY
DROP TABLE IF EXISTS #MeetingAttendance
CREATE TABLE #MeetingAttendance (MeetingID INT,AttendantID INT)
INSERT INTO #MeetingAttendance
VALUES (739,499)
,(739,500)
,(739,501)
SELECT tblMeeting_MeetingId = MeetingID
,tblMeetingAttendants_AttendantNameWithTitle = JSON_QUERY('['+STRING_AGG(CONCAT('"',AttendantID,'"'),',') + ']')
FROM #MeetingAttendance
GROUP BY MeetingID
FOR JSON PATH,WITHOUT_ARRAY_WRAPPER
Results
{
"tblMeeting_MeetingId": 739,
"tblMeetingAttendants_AttendantNameWithTitle": [
"499",
"500",
"501"
]
}

Related

How to create a SQL statement to produce nested JSON from variables?

I have managed to create SQL for the individual nodes, but cannot deduce how to refine the statement to include or merge both outputs.
DECLARE
#FulfillmentOrderId BIGINT = 0,
#NotifyCustomer BIT = 1,
#TrackingCompany NVARCHAR(100) = '',
#TrackingNo NVARCHAR(100) = '';
INPUT
SELECT
#NotifyCustomer AS [notify_customer],
#TrackingCompany AS [tracking_info.company],
#TrackingNo AS [tracking_info.number]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
OUTPUT
{
"line_items_by_fulfillment_order": [
{
"fulfillment_order_id": 0
}
]
}
INPUT
SELECT (
SELECT
#FulfillmentOrderId AS [fulfillment_order_id]
FOR JSON PATH
) AS [line_items_by_fulfillment_order]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
OUTPUT
{
"notify_customer": true,
"tracking_info": {
"company": "",
"number": ""
}
}
DESIRED OUTPUT
{
"fulfillment": {
"notify_customer": true,
"tracking_info": {
"company": "",
"number": 0
},
"line_items_by_fulfillment_order": [
{
"fulfillment_order_id": 0
}
]
}
}
You need to build the nested "line_items_by_fulfillment_order" JSON array and change the paths:
SELECT
#NotifyCustomer AS [fulfillment.notify_customer],
#TrackingCompany AS [fulfillment.tracking_info.company],
#TrackingNo AS [fulfillment.tracking_info.number],
(SELECT #FulfillmentOrderId AS fulfillment_order_id FOR JSON PATH) AS [fulfillment.line_items_by_fulfillment_order]
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
SQL Server 2022 introduced new JSON features, so the following statement is also an option:
SELECT JSON_OBJECT(
'fulfillment': JSON_OBJECT(
'notify_customer': #NotifyCustomer,
'tracking_info': JSON_OBJECT('company': #TrackingCompany, 'number': #TrackingNo),
'line_items_by_fulfillment_order': JSON_ARRAY(JSON_OBJECT('fulfillment_order_id': #FulfillmentOrderId))
)
)
Result:
{
"fulfillment":{
"notify_customer":true,
"tracking_info":{"company":"","number":""},
"line_items_by_fulfillment_order":[{"fulfillment_order_id":0}]
}
}

How to write an SQL query to genearte the empty json objects inside json object

I need an SQL query to get the below JSON object. I tried with FOR JSON PATH. Upto Model object I can get it. But inside JSON objects are not coming.
{
"Model": [
{
"ModelName": "Registration",
"Version": 1,
"Student": [
{
"StudentID": null,
"StudentName": null,
"Work": [
{
"WorkID": null,
"WorkNameName": null,
"Note": [
{
"NoteID": null,
"Comments": null,
"Visible": [
{
"IsVisible": null
}
]
}
]
}
]
}
]
}
]
}
Defining an nvarchar(max) variable (which is a valid JSON object) is always an option, but you may try to format the query results from a SELECT statement as JSON using FOR JSON AUTO. In this case the structure of the output JSON depends on the structure of the SELECT statement.
Statement:
DECLARE #ScriptData nvarchar(max)
SET #ScriptData =
(
SELECT
Model.ModelName, Model.Version,
Student.StudentID, Student.StudentName,
Work.WorkID, Work.WorkNameName,
Note.NoteID, Note.Comments,
Visible.IsVisible
FROM (VALUES ('Registration', 1)) Model (ModelName, Version)
CROSS APPLY (VALUES (NULL, NULL)) Student (StudentID, StudentName)
CROSS APPLY (VALUES (NULL, NULL)) Work (WorkID, WorkNameName)
CROSS APPLY (VALUES (NULL, NULL)) Note (NoteID, Comments)
CROSS APPLY (VALUES (NULL)) Visible (IsVisible)
FOR JSON AUTO, ROOT('Model'), INCLUDE_NULL_VALUES
)
Result:
{
"Model":[
{
"ModelName":"Registration",
"Version":1,
"Student":[
{
"StudentID":null,
"StudentName":null,
"Work":[
{
"WorkID":null,
"WorkNameName":null,
"Note":[
{
"NoteID":null,
"Comments":null,
"Visible":[
{
"IsVisible":null
}
]
}
]
}
]
}
]
}
]
}

How to query field inside nested arrays in CosmosDB SQL

How can I return all documents which have parameter.code = "123", given this document structure, using CosmosDB SQL query? Is it necessary to use a UDF? (If so, how?)
{
"batch_id": "abc",
"samples": [
{
"sample_id": "123",
"tests": [
{
"parameter": {
"code": "123", // <- target
}
}
]
}
]
}
No need to use UDF(User Defined Function),just use cosmos db query sql with double JOIN.
SQL:
SELECT c.batch_id FROM c
join samples in c.samples
join tests in samples.tests
where tests.parameter.code = "123"
Output:

Invalid column name on stream analytics, when column exists

Given this dataset:
[
{
"dataChannelId": 8516,
"measures": [
{
"dateTime": "2019-01-01T12:00:00",
},
{
"dateTime": "2019-01-02T12:00:00",
}
}]
And this query:
WITH
temp AS
(
SELECT
dataChannelId,
arrayElement.ArrayValue as element
FROM GriegInputStream
CROSS APPLY GetArrayElements([mesurasdfes]) AS arrayElement
)
SELECT
temp.dataChannelId as sensorId, temp.element.dateTime, temp.element.value,temp.element.unit,temp.element.maxValue, temp.element.minValue
INTO
Sensoroutput
FROM
temp
I get invalid column name, does not exist on dataChannelId, but measures seem to work fine. How can I access this value without stream analytics complaining?
Your sample json data lack a square bracket ].
sample data:
[
{
"dataChannelId": 8516,
"measures": [
{
"dateTime": "2019-01-01T12:00:00",
},
{
"dateTime": "2019-01-02T12:00:00",
}
]
}
]
Query sql:
WITH
temp AS
(
SELECT
jsoninput.dataChannelId,
arrayElement.ArrayValue as element
FROM jsoninput
CROSS APPLY GetArrayElements(jsoninput.measures) AS arrayElement
)
SELECT
temp.dataChannelId as sensorId, temp.element.dateTime
INTO
Sensoroutput
FROM
temp
Output:

How to access a particular set of keys in array of Json values which i get as response?

For a particular API , I get a response which is similar to the following .
[
{ "name":"Ford", "model":"Mustang" },
{ "name":"BMW", "model": "320" },
{ "name":"Fiat", "model": "500" }
]
I want to store the values for the key 'name' in a separate variable .
Please read the documentation on using JsonPath carefully: https://github.com/intuit/karate#get
Here is an example which works with your data:
* def response =
"""
[
{ "name":"Ford", "model":"Mustang" },
{ "name":"BMW", "model": "320" },
{ "name":"Fiat", "model": "500" }
]
"""
* def names = $[*].name
* match names == ['Ford', 'BMW', 'Fiat']