Skip to content
Advertisement

How do I return NULL conditionally from a JSON_QUERY

How do I return a JSON_QUERY that returns NULL (or no property at all) if the selected value from the sub-query (or left join) is empty?

Here is a simple example (imagine NULL below is a sub-query):

SELECT 
    JSON_QUERY((SELECT NULL as SomeColumn 
                FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)) AS Test

This returns and empty JSON object – which is not what I want:

Test
----------------
{}

Since NULL is being returned from the sub-query, I want it to return NULL if the subquery returns NULL, otherwise it should return JSON.

i.e.

When the Subquery returns NULL, the JSON result should be:

Test
----------------
NULL

When the Subquery returns JSON, the JSON result should be:

Test
----------------
{ someColumn: 'some json' ... }

How do I do this with a JSON query?

[Edit]

I tried this, thinking I could just do a CASE statement:

SELECT 
    JSON_QUERY((SELECT JSON_VALUE('{"SomeColumn":"Test"}', '$') AS SomeColumn 
                FOR JSON PATH, WITHOUT_ARRAY_WRAPPER)) AS Test

But this won’t select the root. The above returns:

Test
------
{}

USE CASE

The use case that I’m after is this.

When I return a JSON query, I want to be able to return something like this when the address exists:

   { 
      name: 'John',
      address: {
         line1: '123 elm st'
      }
   }

OR if there is no address record, I want it to return:

   { 
      name: 'John',
      address: NULL
   }

OR

   { 
      name: 'John'
   }

I DON’T want it to return

   { 
      name: 'John',
      address: {}
   }

Advertisement

Answer

I found a simple solution to this.

To return NULL properties conditionally when the record from the left join (or subquery) does not exist, use “dot-notation” properties:

SELECT
    EMP.firstName as [Employee.FirstName],
    EMP.lastName as [Employee.LastName],
    A.Line1 as [Employee.Address.Line1],
    A.City as [Employee.Address.City]
FROM
   Employee EMP
LEFT OUTER JOIN Address A ON A.Id = EMP.AddressId
FOR JSON PATH

This will return the following when the employee has an Address:

{
   employee: {
       firstName: 'john',
       lastName: 'smith',
       address: {
          line1: 'elm st',
          city: 'New York'
       }
   } 
}

But if the employee does not have an Address record, the query will return this:

{
   employee: {
       firstName: 'john',
       lastName: 'smith'
   } 
}

Note:

  • You need to make sure all dot notation properties are grouped so that properties and sub properties are together
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement