Update:
The original question was edited and I don't think that you can generate the expected ouptut using a single FOR JSON
and INCLUDE_NULL_VALUES
, because now the table has more than one column with NULL
values (OtherField
in the example).
As a possible solution you may try a mixed approach (using FOR JSON
and STRING_AGG()
) to build the final JSON output and keep the NULL
values for all columns, except Phones
:
CREATE TABLE Data (
Id int,
Name varchar(100),
Phone varchar(100),
OtherField varchar(1)
);
INSERT INTO Data (Id, Name, Phone, OtherField)
VALUES
(1, 'ABC', '12344', NULL),
(2, 'ABC', NULL, NULL),
(3, 'ABC', NULL, NULL)
Statement:
SELECT CONCAT(
'[',
(
SELECT STRING_AGG(j.Json, ',')
FROM Data d
CROSS APPLY (
SELECT CASE
WHEN Phone IS NOT NULL THEN (
SELECT Id, Name, (SELECT Phone AS Home FOR JSON PATH) AS Phone, OtherField
FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
)
ELSE (
SELECT Id, Name, OtherField
FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER
)
END
) j (Json)
),
']'
)
Result:
[
{"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}],"OtherField":null},
{"Id":2,"Name":"ABC","OtherField":null},
{"Id":3,"Name":"ABC","OtherField":null}
]
Original answer:
You may try the following statement:
Table:
CREATE TABLE Data (
Id int,
Name varchar(100),
Phone varchar(100)
);
INSERT INTO Data (Id, Name, Phone)
VALUES
(1, 'ABC', '12344'),
(2, 'ABC', NULL )
Statement:
SELECT
Id,
Name,
JSON_QUERY(CASE WHEN Phone IS NOT NULL THEN (SELECT Phone AS Home FOR JSON PATH) END) AS Phone
FROM Data
FOR JSON PATH
Result:
[
{"Id":1,"Name":"ABC","Phone":[{"Home":"12344"}]},
{"Id":2,"Name":"ABC"}
]