Grouping results from stored procedure as JSON - Azure SQL











up vote
0
down vote

favorite












I have a Stored proc returning data in roughly this format



ID | Field1 | Field2 | Group  | Description
------------------------------------------------
1 | A | A | g1 | g1A description
1 | A | A | g2 | g2A description
2 | B | B | g1 | g1B description
2 | B | B | g2 | g2B description
3 | C | C | g1 | g1C description
3 | C | C | g2 | g2C description


SELECT
a.ID,
a.Field1,
b.Field2,
c.Group,
c.Description
FROM A as a
INNER JOIN B b ...
INNER JOIN C c ...


In code, I am converting the dataset to JSON



[
{
ID: 1,
Field1: A,
Field2: A,
Groups: {
g1: g1A description,
g2: g2A description,
}
}, {
ID: 2,
Field1: B,
Field2: B,
Groups: {
g1: g1B description,
g2: g2B description,
}
}, {
ID: 1,
Field1: C,
Field2: C,
Groups: {
g1: g1C description,
g2: g2C description,
}
}
]


I don't like that the procedure is returning mostly duplicate data in each row. Is there some way I can perform the grouping in SQL, so that the returned dataset is something like



ID | Field1 | Field2 | Groups  
------------------------------------------------
1 | A | A | 'Groups: { g1: g1A description, g2: g2A description }'
2 | B | B | 'Groups: { g1: g1B description, g2: g2B description }'
3 | C | C | 'Groups: { g1: g1C description, g2: g2C description }'


OR



 ID | Field1 | Field2 |        g1       |        g2
----------------------------------------------------------
1 | A | A | g1A description | g2A description
2 | B | B | g1B description | g2B description
3 | C | C | g1C description | g2C description




Using the answer from 'D-Shih, I came up with this:



   SELECT
a.ID,
a.Field1,
b.Field2,
(
SELECT
MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) as Groups
FROM A as a
INNER JOIN B b ...
INNER JOIN C c ...


ID | Field1 | Field2 | Groups
------------------------------------------------
1 | A | A | '{ "g1": "g1A description", "g2": "g2A description" }'
2 | B | B | '{ "g1": "g1B description", "g2": "g2B description" }'
3 | C | C | '{ "g1": "g1C description", "g2": "g2C description" }'


https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=4bf8a009fe91bbbd0f3246723a1f9eb4










share|improve this question
























  • You can't use the results of a stored procedure in a query. If you want to do so, you'll need to convert it to a function. If you want to generate JSON though, why not write a different query that uses FOR JSON?
    – Panagiotis Kanavos
    Nov 8 at 13:22












  • Which SQL Server version are you using? In SQL Server 2016 and later you could just add FOR JSON AUTO to get a JSON string with the results nested per table or FOR JSON PATH to specify the nesting through column names
    – Panagiotis Kanavos
    Nov 8 at 13:27










  • @PanagiotisKanavos I'm using Azure SQL so I do have access to the JSON functionality
    – Eamonn McEvoy
    Nov 8 at 13:43















up vote
0
down vote

favorite












I have a Stored proc returning data in roughly this format



ID | Field1 | Field2 | Group  | Description
------------------------------------------------
1 | A | A | g1 | g1A description
1 | A | A | g2 | g2A description
2 | B | B | g1 | g1B description
2 | B | B | g2 | g2B description
3 | C | C | g1 | g1C description
3 | C | C | g2 | g2C description


SELECT
a.ID,
a.Field1,
b.Field2,
c.Group,
c.Description
FROM A as a
INNER JOIN B b ...
INNER JOIN C c ...


In code, I am converting the dataset to JSON



[
{
ID: 1,
Field1: A,
Field2: A,
Groups: {
g1: g1A description,
g2: g2A description,
}
}, {
ID: 2,
Field1: B,
Field2: B,
Groups: {
g1: g1B description,
g2: g2B description,
}
}, {
ID: 1,
Field1: C,
Field2: C,
Groups: {
g1: g1C description,
g2: g2C description,
}
}
]


I don't like that the procedure is returning mostly duplicate data in each row. Is there some way I can perform the grouping in SQL, so that the returned dataset is something like



ID | Field1 | Field2 | Groups  
------------------------------------------------
1 | A | A | 'Groups: { g1: g1A description, g2: g2A description }'
2 | B | B | 'Groups: { g1: g1B description, g2: g2B description }'
3 | C | C | 'Groups: { g1: g1C description, g2: g2C description }'


OR



 ID | Field1 | Field2 |        g1       |        g2
----------------------------------------------------------
1 | A | A | g1A description | g2A description
2 | B | B | g1B description | g2B description
3 | C | C | g1C description | g2C description




Using the answer from 'D-Shih, I came up with this:



   SELECT
a.ID,
a.Field1,
b.Field2,
(
SELECT
MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) as Groups
FROM A as a
INNER JOIN B b ...
INNER JOIN C c ...


ID | Field1 | Field2 | Groups
------------------------------------------------
1 | A | A | '{ "g1": "g1A description", "g2": "g2A description" }'
2 | B | B | '{ "g1": "g1B description", "g2": "g2B description" }'
3 | C | C | '{ "g1": "g1C description", "g2": "g2C description" }'


https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=4bf8a009fe91bbbd0f3246723a1f9eb4










share|improve this question
























  • You can't use the results of a stored procedure in a query. If you want to do so, you'll need to convert it to a function. If you want to generate JSON though, why not write a different query that uses FOR JSON?
    – Panagiotis Kanavos
    Nov 8 at 13:22












  • Which SQL Server version are you using? In SQL Server 2016 and later you could just add FOR JSON AUTO to get a JSON string with the results nested per table or FOR JSON PATH to specify the nesting through column names
    – Panagiotis Kanavos
    Nov 8 at 13:27










  • @PanagiotisKanavos I'm using Azure SQL so I do have access to the JSON functionality
    – Eamonn McEvoy
    Nov 8 at 13:43













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a Stored proc returning data in roughly this format



ID | Field1 | Field2 | Group  | Description
------------------------------------------------
1 | A | A | g1 | g1A description
1 | A | A | g2 | g2A description
2 | B | B | g1 | g1B description
2 | B | B | g2 | g2B description
3 | C | C | g1 | g1C description
3 | C | C | g2 | g2C description


SELECT
a.ID,
a.Field1,
b.Field2,
c.Group,
c.Description
FROM A as a
INNER JOIN B b ...
INNER JOIN C c ...


In code, I am converting the dataset to JSON



[
{
ID: 1,
Field1: A,
Field2: A,
Groups: {
g1: g1A description,
g2: g2A description,
}
}, {
ID: 2,
Field1: B,
Field2: B,
Groups: {
g1: g1B description,
g2: g2B description,
}
}, {
ID: 1,
Field1: C,
Field2: C,
Groups: {
g1: g1C description,
g2: g2C description,
}
}
]


I don't like that the procedure is returning mostly duplicate data in each row. Is there some way I can perform the grouping in SQL, so that the returned dataset is something like



ID | Field1 | Field2 | Groups  
------------------------------------------------
1 | A | A | 'Groups: { g1: g1A description, g2: g2A description }'
2 | B | B | 'Groups: { g1: g1B description, g2: g2B description }'
3 | C | C | 'Groups: { g1: g1C description, g2: g2C description }'


OR



 ID | Field1 | Field2 |        g1       |        g2
----------------------------------------------------------
1 | A | A | g1A description | g2A description
2 | B | B | g1B description | g2B description
3 | C | C | g1C description | g2C description




Using the answer from 'D-Shih, I came up with this:



   SELECT
a.ID,
a.Field1,
b.Field2,
(
SELECT
MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) as Groups
FROM A as a
INNER JOIN B b ...
INNER JOIN C c ...


ID | Field1 | Field2 | Groups
------------------------------------------------
1 | A | A | '{ "g1": "g1A description", "g2": "g2A description" }'
2 | B | B | '{ "g1": "g1B description", "g2": "g2B description" }'
3 | C | C | '{ "g1": "g1C description", "g2": "g2C description" }'


https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=4bf8a009fe91bbbd0f3246723a1f9eb4










share|improve this question















I have a Stored proc returning data in roughly this format



ID | Field1 | Field2 | Group  | Description
------------------------------------------------
1 | A | A | g1 | g1A description
1 | A | A | g2 | g2A description
2 | B | B | g1 | g1B description
2 | B | B | g2 | g2B description
3 | C | C | g1 | g1C description
3 | C | C | g2 | g2C description


SELECT
a.ID,
a.Field1,
b.Field2,
c.Group,
c.Description
FROM A as a
INNER JOIN B b ...
INNER JOIN C c ...


In code, I am converting the dataset to JSON



[
{
ID: 1,
Field1: A,
Field2: A,
Groups: {
g1: g1A description,
g2: g2A description,
}
}, {
ID: 2,
Field1: B,
Field2: B,
Groups: {
g1: g1B description,
g2: g2B description,
}
}, {
ID: 1,
Field1: C,
Field2: C,
Groups: {
g1: g1C description,
g2: g2C description,
}
}
]


I don't like that the procedure is returning mostly duplicate data in each row. Is there some way I can perform the grouping in SQL, so that the returned dataset is something like



ID | Field1 | Field2 | Groups  
------------------------------------------------
1 | A | A | 'Groups: { g1: g1A description, g2: g2A description }'
2 | B | B | 'Groups: { g1: g1B description, g2: g2B description }'
3 | C | C | 'Groups: { g1: g1C description, g2: g2C description }'


OR



 ID | Field1 | Field2 |        g1       |        g2
----------------------------------------------------------
1 | A | A | g1A description | g2A description
2 | B | B | g1B description | g2B description
3 | C | C | g1C description | g2C description




Using the answer from 'D-Shih, I came up with this:



   SELECT
a.ID,
a.Field1,
b.Field2,
(
SELECT
MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
) as Groups
FROM A as a
INNER JOIN B b ...
INNER JOIN C c ...


ID | Field1 | Field2 | Groups
------------------------------------------------
1 | A | A | '{ "g1": "g1A description", "g2": "g2A description" }'
2 | B | B | '{ "g1": "g1B description", "g2": "g2B description" }'
3 | C | C | '{ "g1": "g1C description", "g2": "g2C description" }'


https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=4bf8a009fe91bbbd0f3246723a1f9eb4







sql sql-server






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 9 at 8:10

























asked Nov 8 at 13:19









Eamonn McEvoy

4,788114369




4,788114369












  • You can't use the results of a stored procedure in a query. If you want to do so, you'll need to convert it to a function. If you want to generate JSON though, why not write a different query that uses FOR JSON?
    – Panagiotis Kanavos
    Nov 8 at 13:22












  • Which SQL Server version are you using? In SQL Server 2016 and later you could just add FOR JSON AUTO to get a JSON string with the results nested per table or FOR JSON PATH to specify the nesting through column names
    – Panagiotis Kanavos
    Nov 8 at 13:27










  • @PanagiotisKanavos I'm using Azure SQL so I do have access to the JSON functionality
    – Eamonn McEvoy
    Nov 8 at 13:43


















  • You can't use the results of a stored procedure in a query. If you want to do so, you'll need to convert it to a function. If you want to generate JSON though, why not write a different query that uses FOR JSON?
    – Panagiotis Kanavos
    Nov 8 at 13:22












  • Which SQL Server version are you using? In SQL Server 2016 and later you could just add FOR JSON AUTO to get a JSON string with the results nested per table or FOR JSON PATH to specify the nesting through column names
    – Panagiotis Kanavos
    Nov 8 at 13:27










  • @PanagiotisKanavos I'm using Azure SQL so I do have access to the JSON functionality
    – Eamonn McEvoy
    Nov 8 at 13:43
















You can't use the results of a stored procedure in a query. If you want to do so, you'll need to convert it to a function. If you want to generate JSON though, why not write a different query that uses FOR JSON?
– Panagiotis Kanavos
Nov 8 at 13:22






You can't use the results of a stored procedure in a query. If you want to do so, you'll need to convert it to a function. If you want to generate JSON though, why not write a different query that uses FOR JSON?
– Panagiotis Kanavos
Nov 8 at 13:22














Which SQL Server version are you using? In SQL Server 2016 and later you could just add FOR JSON AUTO to get a JSON string with the results nested per table or FOR JSON PATH to specify the nesting through column names
– Panagiotis Kanavos
Nov 8 at 13:27




Which SQL Server version are you using? In SQL Server 2016 and later you could just add FOR JSON AUTO to get a JSON string with the results nested per table or FOR JSON PATH to specify the nesting through column names
– Panagiotis Kanavos
Nov 8 at 13:27












@PanagiotisKanavos I'm using Azure SQL so I do have access to the JSON functionality
– Eamonn McEvoy
Nov 8 at 13:43




@PanagiotisKanavos I'm using Azure SQL so I do have access to the JSON functionality
– Eamonn McEvoy
Nov 8 at 13:43












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










Your second expect result can use condition aggregate function to make it.



SELECT ID,
Field1,
Field2,
MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
FROM T
GROUP BY ID,Field1,Field2


SQLFIDDLE



NOTE



T is your currently result set.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53208586%2fgrouping-results-from-stored-procedure-as-json-azure-sql%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    Your second expect result can use condition aggregate function to make it.



    SELECT ID,
    Field1,
    Field2,
    MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
    MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
    FROM T
    GROUP BY ID,Field1,Field2


    SQLFIDDLE



    NOTE



    T is your currently result set.






    share|improve this answer

























      up vote
      1
      down vote



      accepted










      Your second expect result can use condition aggregate function to make it.



      SELECT ID,
      Field1,
      Field2,
      MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
      MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
      FROM T
      GROUP BY ID,Field1,Field2


      SQLFIDDLE



      NOTE



      T is your currently result set.






      share|improve this answer























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        Your second expect result can use condition aggregate function to make it.



        SELECT ID,
        Field1,
        Field2,
        MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
        MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
        FROM T
        GROUP BY ID,Field1,Field2


        SQLFIDDLE



        NOTE



        T is your currently result set.






        share|improve this answer












        Your second expect result can use condition aggregate function to make it.



        SELECT ID,
        Field1,
        Field2,
        MAX(CASE WHEN [Group] = 'g1' THEN Description END) g1,
        MAX(CASE WHEN [Group] = 'g2' THEN Description END) g2
        FROM T
        GROUP BY ID,Field1,Field2


        SQLFIDDLE



        NOTE



        T is your currently result set.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 8 at 13:23









        D-Shih

        24k61331




        24k61331






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53208586%2fgrouping-results-from-stored-procedure-as-json-azure-sql%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)