0

I have a problem coming up with a way to solve this problem. Namely, I want the second SELECT statement to return null values even if the row is not found using the WHERE clause.

I tried many different solutions, but nothing worked (using IF, CTE, etc.). Can you please help?

    SELECT  RA.id
        ,AllEngagementsAndJobCodes =
        (
            SELECT 
            (
                SELECT
                (...)

                For JSON Path
            ) AS  engagements
            ,
            (
                SELECT [someColumn] as [id], [someColumn2] as [name]
                FROM [someInterface].[someSchema].[someTable]
                WHERE [someID] = '12345'

                For JSON Path, INCLUDE_NULL_VALUES
            ) as jobCodes
        For JSON Path, WITHOUT_ARRAY_WRAPPER
        )

The output of this should be one column (which is trivial for this question) and the second column containing the JSON path, which should look something like this:

    {
        "engagements": [
            {
                //results of the first query, not siginificant for the question
            }
        ],
        "jobCodes": [
            {
                "id": null,
                "name": null
            }
        ]
    }

Note that if the query DOES return something, it might be more than one row and all of them need to be included in the output JSON.

3
  • You should probably provide a working query, sample data, current and expected results to clarify your requirement. Commented Feb 5, 2020 at 9:41
  • I'll use a LEFT JOIN with the same table, with no conditions on the LEFT component and COALESCE for the right elements. If you provide a working sample, I can try to rewrite the query this way. Commented Feb 5, 2020 at 9:48
  • Well this is a working sample Commented Feb 5, 2020 at 9:58

2 Answers 2

1

One way to do it is using a common table expression and union all:

;WITH CTEInnerQuery AS
(
    SELECT [someColumn] as [id], [someColumn2] as [name]
    FROM [someInterface].[someSchema].[someTable]
    WHERE [someID] = '12345'
), CTEInnerJson AS
(
    SELECT *
    FROM CTEInnerQuery
    UNION ALL
    SELECT NULL as [id], NULL as [name]
    WHERE NOT EXISTS(SELECT 1 FROM CTEInnerQuery)
)

SELECT  RA.id
    ,AllEngagementsAndJobCodes =
    (
        SELECT 
        (
            SELECT
            (...)

            For JSON Path
        ) AS  engagements
        ,
        (
            SELECT *
            FROM CTEInnerJson
            For JSON Path, INCLUDE_NULL_VALUES
        ) as jobCodes
    For JSON Path, WITHOUT_ARRAY_WRAPPER
    )
Sign up to request clarification or add additional context in comments.

4 Comments

When I try to run this, I get the error: The FOR XML and FOR JSON clauses are invalid in views, inline functions, derived tables, and subqueries when they contain a set operator. To work around, wrap the SELECT containing a set operator using derived table or common table expression or view and apply FOR XML or FOR JSON on top of it. and when I wrap the inner query in another SELECT, I get this error: All queries combined using a UNION, INTERSECT or EXCEPT operator must have an equal number of expressions in their target lists.
Sorry, I've edited my answer. Please try the updated code.
It works! Thank you so much, I spent 2 days trying to figure this out..
Glad to help :-)
0

You can use this trick the resolve your problem

IF(NOT EXISTS (...))
BEGIN
    SELECT  0 AS UserID
            ,N'' UserName
    WHERE 1 = 2

    RETURN;
END

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.