Group String Concatenation: which approach, if any, is any more guaranteed?












4














Itzik Ben-Gan explains in his book 'Inside Microsoft® SQL Server® 2008: T-SQL' how Appoach A works, because of the undocumented behavior of SQL Server in which it performs assignment for each result record from the SELECT.



A well respected collegue and DB guru has suggested that Approach B is guaranteed to work. His argument is based on the recursive nature of COALESCE versus the 'values expansion' method of CAST.



Actually, I have no idea what 'values expansion' refers to (except for the fact that it is casting one value to another) or how it applies to this problem? Perhaps he misunderstood? Yes COALESCE is recursive in a sense, but as far as I can see it is irrelevant and the desired result is produced because of the undocumented behavior of multiple assignment.



Is he correct? Please, no "Use FOR XML PATH instead" answers!



Approach A



DECLARE @output VARCHAR(100);
SET @output = '';

SELECT @output = @output + CAST(COL_VCHAR AS VARCHAR(10)) + ';'
FROM someTable;


Approach B



DECLARE @output VARCHAR(100);
SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR
from someTable;









share|improve this question
























  • Have you tried it?
    – Adrian Carneiro
    Feb 16 '12 at 18:49










  • @Adrian They both work. Question is not if they work, but if I am correct in saying that they both work because of the same undocumented behavior?
    – J Cooper
    Feb 16 '12 at 18:57
















4














Itzik Ben-Gan explains in his book 'Inside Microsoft® SQL Server® 2008: T-SQL' how Appoach A works, because of the undocumented behavior of SQL Server in which it performs assignment for each result record from the SELECT.



A well respected collegue and DB guru has suggested that Approach B is guaranteed to work. His argument is based on the recursive nature of COALESCE versus the 'values expansion' method of CAST.



Actually, I have no idea what 'values expansion' refers to (except for the fact that it is casting one value to another) or how it applies to this problem? Perhaps he misunderstood? Yes COALESCE is recursive in a sense, but as far as I can see it is irrelevant and the desired result is produced because of the undocumented behavior of multiple assignment.



Is he correct? Please, no "Use FOR XML PATH instead" answers!



Approach A



DECLARE @output VARCHAR(100);
SET @output = '';

SELECT @output = @output + CAST(COL_VCHAR AS VARCHAR(10)) + ';'
FROM someTable;


Approach B



DECLARE @output VARCHAR(100);
SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR
from someTable;









share|improve this question
























  • Have you tried it?
    – Adrian Carneiro
    Feb 16 '12 at 18:49










  • @Adrian They both work. Question is not if they work, but if I am correct in saying that they both work because of the same undocumented behavior?
    – J Cooper
    Feb 16 '12 at 18:57














4












4








4







Itzik Ben-Gan explains in his book 'Inside Microsoft® SQL Server® 2008: T-SQL' how Appoach A works, because of the undocumented behavior of SQL Server in which it performs assignment for each result record from the SELECT.



A well respected collegue and DB guru has suggested that Approach B is guaranteed to work. His argument is based on the recursive nature of COALESCE versus the 'values expansion' method of CAST.



Actually, I have no idea what 'values expansion' refers to (except for the fact that it is casting one value to another) or how it applies to this problem? Perhaps he misunderstood? Yes COALESCE is recursive in a sense, but as far as I can see it is irrelevant and the desired result is produced because of the undocumented behavior of multiple assignment.



Is he correct? Please, no "Use FOR XML PATH instead" answers!



Approach A



DECLARE @output VARCHAR(100);
SET @output = '';

SELECT @output = @output + CAST(COL_VCHAR AS VARCHAR(10)) + ';'
FROM someTable;


Approach B



DECLARE @output VARCHAR(100);
SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR
from someTable;









share|improve this question















Itzik Ben-Gan explains in his book 'Inside Microsoft® SQL Server® 2008: T-SQL' how Appoach A works, because of the undocumented behavior of SQL Server in which it performs assignment for each result record from the SELECT.



A well respected collegue and DB guru has suggested that Approach B is guaranteed to work. His argument is based on the recursive nature of COALESCE versus the 'values expansion' method of CAST.



Actually, I have no idea what 'values expansion' refers to (except for the fact that it is casting one value to another) or how it applies to this problem? Perhaps he misunderstood? Yes COALESCE is recursive in a sense, but as far as I can see it is irrelevant and the desired result is produced because of the undocumented behavior of multiple assignment.



Is he correct? Please, no "Use FOR XML PATH instead" answers!



Approach A



DECLARE @output VARCHAR(100);
SET @output = '';

SELECT @output = @output + CAST(COL_VCHAR AS VARCHAR(10)) + ';'
FROM someTable;


Approach B



DECLARE @output VARCHAR(100);
SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR
from someTable;






sql sql-server-2008 tsql






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 16 '12 at 19:16









Aaron Bertrand

207k27361404




207k27361404










asked Feb 16 '12 at 18:44









J Cooper

3,44022739




3,44022739












  • Have you tried it?
    – Adrian Carneiro
    Feb 16 '12 at 18:49










  • @Adrian They both work. Question is not if they work, but if I am correct in saying that they both work because of the same undocumented behavior?
    – J Cooper
    Feb 16 '12 at 18:57


















  • Have you tried it?
    – Adrian Carneiro
    Feb 16 '12 at 18:49










  • @Adrian They both work. Question is not if they work, but if I am correct in saying that they both work because of the same undocumented behavior?
    – J Cooper
    Feb 16 '12 at 18:57
















Have you tried it?
– Adrian Carneiro
Feb 16 '12 at 18:49




Have you tried it?
– Adrian Carneiro
Feb 16 '12 at 18:49












@Adrian They both work. Question is not if they work, but if I am correct in saying that they both work because of the same undocumented behavior?
– J Cooper
Feb 16 '12 at 18:57




@Adrian They both work. Question is not if they work, but if I am correct in saying that they both work because of the same undocumented behavior?
– J Cooper
Feb 16 '12 at 18:57












4 Answers
4






active

oldest

votes


















2














Since a conforming SQL implementation could evaluate all of the output rows simultaneously, in parallel, neither is guaranteed to work. That they happen to work, today, is an artifact of the current SQL Server implementation.



Your colleague is incorrect to assert that COALESCE somehow changes the processing model.



I.e. a conforming implementation could effectively hand each potential row in the result set (having evaluated FROM and WHERE) to a separate thread, that then performs whatever processing is required in the SELECT clause (before presumably recombining results in order to assess GROUP BY, HAVING and ORDER BY).



There are no standard requirements governing access to variables during such processing, so each thread could "see" the same initial value of @output (NULL or '', depending on which form you're using), perform it's own update calculation, and assign that result value to @output - the final value of @output might then any of the individual row results - or anything else for that matter.






share|improve this answer































    4














    I believe they both work because of the same underlying (and undocumented) behavior. I am fairly confident that if you take a case where Itzik has demonstrated that Approach A fails, that Approach B will also fail in the same way and for the same reasons, in spite of your colleague's claims. I don't see how



    DECLARE @output VARCHAR(100);
    SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR


    Is any different from:



    DECLARE @output VARCHAR(100) = '';
    SELECT @output = @output + ', ' + COL_VCHAR
    -- or SELECT @output += ',' + COL_VCHAR


    So what exactly does COALESCE magically introduce? SQL Server isn't going to change its plan because of something you're doing to the output, AFAIK.



    I use them all the time for dynamic SQL generation and don't recall ever seeing them fail, and I realize that's not your question. Unfortunately there isn't really a way to prove it unless you know of a case that fails for either approach.



    I wrote a blog post about string concatenation a few months ago. It's not completely relevant to your problem but Rob Farley made a comment that may be considered another downside to the COALESCE approach:



    https://sqlblog.org/2011/03/08/t-sql-tuesday-16-this-is-not-the-aggregate-youre-looking-for






    share|improve this answer























    • Thanks for your input. The concern is relying on an undocumented behavior/feature in a massive production system. Some hotfix down the road, microsoft decides to do things different behind the scenes and this no longer works and breaks things.
      – J Cooper
      Feb 16 '12 at 19:07










    • Both can fail if if you want a specific order of the concatenated values. Not the case here but if you do, for xml is the way to go.
      – Mikael Eriksson
      Feb 16 '12 at 19:09










    • If your concern is forward compatibility then I would say both approaches introduce the same level of risk. With that in mind FOR XML is, as @Mikael suggests for other reasons, probably the most future-proof method. I realize that's not what you want to hear, but better safe than sorry. It's quite easy to encapsulate this kind of thing - how many different queries are you doing this concatenation for? If it is a lot then perhaps the data model should be a more important concern.
      – Aaron Bertrand
      Feb 16 '12 at 19:12












    • I read your article - you sure would be the right guy to answer this question! Yes, I thought FOR XML would be the safe, supported way to go. Actually, Ben-Gan suggests this method in his book. As far as the data model, the data is pulled this way for presentational purposes a good bit - but not my call
      – J Cooper
      Feb 17 '12 at 0:54










    • @J Cooper one other comment. If guaranteeing future compatibility (or order) is paramount to strict performance, use a cursor. Anything else is an undocumented trick.
      – Aaron Bertrand
      Feb 17 '12 at 12:40



















    0














    In your example, there is a way to get different results, and that is if NULL values are introduced into the data set. e.g.:



    set nocount on

    declare @test table (value int)

    insert into @test values (10)
    insert into @test values (20)
    insert into @test values (null)
    insert into @test values (40)
    insert into @test values (50)

    DECLARE @output VARCHAR(max);

    -- Approach A
    SET @output = '';

    SELECT @output = @output + CAST(value AS VARCHAR(10)) + ';'
    FROM @test

    print 'Result from A:'
    print isnull(@output, '{null}')

    -- Approach B
    set @output = ''
    SELECT @output = COALESCE(@output + ', ', '') + cast(value as varchar(10))
    from @test

    print 'Result from B:'
    print isnull(@output, '{null}')

    set nocount off


    Approach A will return null, whereas Approach B will return 40, 50






    share|improve this answer





























      0














      They work differently, the first example adds an additional character to the end of the output variable, and yes they work because of the same behaviour.



      The first example will work if your column had been a numeric or date also. It would however only take the first 10 characters of any value in the column. The second example would not cut off the column.



      There is absolutely no recursive nature of COALESCE.
      COALESCE is a way of replacing null values with replacement values.



      EDIT:



      I should add that i also prefer the second version, because you don't get that extra semicolon, in the end of output implying that more values will follow.






      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',
        autoActivateHeartbeat: false,
        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%2f9317170%2fgroup-string-concatenation-which-approach-if-any-is-any-more-guaranteed%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        2














        Since a conforming SQL implementation could evaluate all of the output rows simultaneously, in parallel, neither is guaranteed to work. That they happen to work, today, is an artifact of the current SQL Server implementation.



        Your colleague is incorrect to assert that COALESCE somehow changes the processing model.



        I.e. a conforming implementation could effectively hand each potential row in the result set (having evaluated FROM and WHERE) to a separate thread, that then performs whatever processing is required in the SELECT clause (before presumably recombining results in order to assess GROUP BY, HAVING and ORDER BY).



        There are no standard requirements governing access to variables during such processing, so each thread could "see" the same initial value of @output (NULL or '', depending on which form you're using), perform it's own update calculation, and assign that result value to @output - the final value of @output might then any of the individual row results - or anything else for that matter.






        share|improve this answer




























          2














          Since a conforming SQL implementation could evaluate all of the output rows simultaneously, in parallel, neither is guaranteed to work. That they happen to work, today, is an artifact of the current SQL Server implementation.



          Your colleague is incorrect to assert that COALESCE somehow changes the processing model.



          I.e. a conforming implementation could effectively hand each potential row in the result set (having evaluated FROM and WHERE) to a separate thread, that then performs whatever processing is required in the SELECT clause (before presumably recombining results in order to assess GROUP BY, HAVING and ORDER BY).



          There are no standard requirements governing access to variables during such processing, so each thread could "see" the same initial value of @output (NULL or '', depending on which form you're using), perform it's own update calculation, and assign that result value to @output - the final value of @output might then any of the individual row results - or anything else for that matter.






          share|improve this answer


























            2












            2








            2






            Since a conforming SQL implementation could evaluate all of the output rows simultaneously, in parallel, neither is guaranteed to work. That they happen to work, today, is an artifact of the current SQL Server implementation.



            Your colleague is incorrect to assert that COALESCE somehow changes the processing model.



            I.e. a conforming implementation could effectively hand each potential row in the result set (having evaluated FROM and WHERE) to a separate thread, that then performs whatever processing is required in the SELECT clause (before presumably recombining results in order to assess GROUP BY, HAVING and ORDER BY).



            There are no standard requirements governing access to variables during such processing, so each thread could "see" the same initial value of @output (NULL or '', depending on which form you're using), perform it's own update calculation, and assign that result value to @output - the final value of @output might then any of the individual row results - or anything else for that matter.






            share|improve this answer














            Since a conforming SQL implementation could evaluate all of the output rows simultaneously, in parallel, neither is guaranteed to work. That they happen to work, today, is an artifact of the current SQL Server implementation.



            Your colleague is incorrect to assert that COALESCE somehow changes the processing model.



            I.e. a conforming implementation could effectively hand each potential row in the result set (having evaluated FROM and WHERE) to a separate thread, that then performs whatever processing is required in the SELECT clause (before presumably recombining results in order to assess GROUP BY, HAVING and ORDER BY).



            There are no standard requirements governing access to variables during such processing, so each thread could "see" the same initial value of @output (NULL or '', depending on which form you're using), perform it's own update calculation, and assign that result value to @output - the final value of @output might then any of the individual row results - or anything else for that matter.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Sep 8 '14 at 22:20









            Riley Major

            1,1481432




            1,1481432










            answered Feb 17 '12 at 10:54









            Damien_The_Unbeliever

            192k17245331




            192k17245331

























                4














                I believe they both work because of the same underlying (and undocumented) behavior. I am fairly confident that if you take a case where Itzik has demonstrated that Approach A fails, that Approach B will also fail in the same way and for the same reasons, in spite of your colleague's claims. I don't see how



                DECLARE @output VARCHAR(100);
                SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR


                Is any different from:



                DECLARE @output VARCHAR(100) = '';
                SELECT @output = @output + ', ' + COL_VCHAR
                -- or SELECT @output += ',' + COL_VCHAR


                So what exactly does COALESCE magically introduce? SQL Server isn't going to change its plan because of something you're doing to the output, AFAIK.



                I use them all the time for dynamic SQL generation and don't recall ever seeing them fail, and I realize that's not your question. Unfortunately there isn't really a way to prove it unless you know of a case that fails for either approach.



                I wrote a blog post about string concatenation a few months ago. It's not completely relevant to your problem but Rob Farley made a comment that may be considered another downside to the COALESCE approach:



                https://sqlblog.org/2011/03/08/t-sql-tuesday-16-this-is-not-the-aggregate-youre-looking-for






                share|improve this answer























                • Thanks for your input. The concern is relying on an undocumented behavior/feature in a massive production system. Some hotfix down the road, microsoft decides to do things different behind the scenes and this no longer works and breaks things.
                  – J Cooper
                  Feb 16 '12 at 19:07










                • Both can fail if if you want a specific order of the concatenated values. Not the case here but if you do, for xml is the way to go.
                  – Mikael Eriksson
                  Feb 16 '12 at 19:09










                • If your concern is forward compatibility then I would say both approaches introduce the same level of risk. With that in mind FOR XML is, as @Mikael suggests for other reasons, probably the most future-proof method. I realize that's not what you want to hear, but better safe than sorry. It's quite easy to encapsulate this kind of thing - how many different queries are you doing this concatenation for? If it is a lot then perhaps the data model should be a more important concern.
                  – Aaron Bertrand
                  Feb 16 '12 at 19:12












                • I read your article - you sure would be the right guy to answer this question! Yes, I thought FOR XML would be the safe, supported way to go. Actually, Ben-Gan suggests this method in his book. As far as the data model, the data is pulled this way for presentational purposes a good bit - but not my call
                  – J Cooper
                  Feb 17 '12 at 0:54










                • @J Cooper one other comment. If guaranteeing future compatibility (or order) is paramount to strict performance, use a cursor. Anything else is an undocumented trick.
                  – Aaron Bertrand
                  Feb 17 '12 at 12:40
















                4














                I believe they both work because of the same underlying (and undocumented) behavior. I am fairly confident that if you take a case where Itzik has demonstrated that Approach A fails, that Approach B will also fail in the same way and for the same reasons, in spite of your colleague's claims. I don't see how



                DECLARE @output VARCHAR(100);
                SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR


                Is any different from:



                DECLARE @output VARCHAR(100) = '';
                SELECT @output = @output + ', ' + COL_VCHAR
                -- or SELECT @output += ',' + COL_VCHAR


                So what exactly does COALESCE magically introduce? SQL Server isn't going to change its plan because of something you're doing to the output, AFAIK.



                I use them all the time for dynamic SQL generation and don't recall ever seeing them fail, and I realize that's not your question. Unfortunately there isn't really a way to prove it unless you know of a case that fails for either approach.



                I wrote a blog post about string concatenation a few months ago. It's not completely relevant to your problem but Rob Farley made a comment that may be considered another downside to the COALESCE approach:



                https://sqlblog.org/2011/03/08/t-sql-tuesday-16-this-is-not-the-aggregate-youre-looking-for






                share|improve this answer























                • Thanks for your input. The concern is relying on an undocumented behavior/feature in a massive production system. Some hotfix down the road, microsoft decides to do things different behind the scenes and this no longer works and breaks things.
                  – J Cooper
                  Feb 16 '12 at 19:07










                • Both can fail if if you want a specific order of the concatenated values. Not the case here but if you do, for xml is the way to go.
                  – Mikael Eriksson
                  Feb 16 '12 at 19:09










                • If your concern is forward compatibility then I would say both approaches introduce the same level of risk. With that in mind FOR XML is, as @Mikael suggests for other reasons, probably the most future-proof method. I realize that's not what you want to hear, but better safe than sorry. It's quite easy to encapsulate this kind of thing - how many different queries are you doing this concatenation for? If it is a lot then perhaps the data model should be a more important concern.
                  – Aaron Bertrand
                  Feb 16 '12 at 19:12












                • I read your article - you sure would be the right guy to answer this question! Yes, I thought FOR XML would be the safe, supported way to go. Actually, Ben-Gan suggests this method in his book. As far as the data model, the data is pulled this way for presentational purposes a good bit - but not my call
                  – J Cooper
                  Feb 17 '12 at 0:54










                • @J Cooper one other comment. If guaranteeing future compatibility (or order) is paramount to strict performance, use a cursor. Anything else is an undocumented trick.
                  – Aaron Bertrand
                  Feb 17 '12 at 12:40














                4












                4








                4






                I believe they both work because of the same underlying (and undocumented) behavior. I am fairly confident that if you take a case where Itzik has demonstrated that Approach A fails, that Approach B will also fail in the same way and for the same reasons, in spite of your colleague's claims. I don't see how



                DECLARE @output VARCHAR(100);
                SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR


                Is any different from:



                DECLARE @output VARCHAR(100) = '';
                SELECT @output = @output + ', ' + COL_VCHAR
                -- or SELECT @output += ',' + COL_VCHAR


                So what exactly does COALESCE magically introduce? SQL Server isn't going to change its plan because of something you're doing to the output, AFAIK.



                I use them all the time for dynamic SQL generation and don't recall ever seeing them fail, and I realize that's not your question. Unfortunately there isn't really a way to prove it unless you know of a case that fails for either approach.



                I wrote a blog post about string concatenation a few months ago. It's not completely relevant to your problem but Rob Farley made a comment that may be considered another downside to the COALESCE approach:



                https://sqlblog.org/2011/03/08/t-sql-tuesday-16-this-is-not-the-aggregate-youre-looking-for






                share|improve this answer














                I believe they both work because of the same underlying (and undocumented) behavior. I am fairly confident that if you take a case where Itzik has demonstrated that Approach A fails, that Approach B will also fail in the same way and for the same reasons, in spite of your colleague's claims. I don't see how



                DECLARE @output VARCHAR(100);
                SELECT @output = COALESCE(@output + ', ', '') + COL_VCHAR


                Is any different from:



                DECLARE @output VARCHAR(100) = '';
                SELECT @output = @output + ', ' + COL_VCHAR
                -- or SELECT @output += ',' + COL_VCHAR


                So what exactly does COALESCE magically introduce? SQL Server isn't going to change its plan because of something you're doing to the output, AFAIK.



                I use them all the time for dynamic SQL generation and don't recall ever seeing them fail, and I realize that's not your question. Unfortunately there isn't really a way to prove it unless you know of a case that fails for either approach.



                I wrote a blog post about string concatenation a few months ago. It's not completely relevant to your problem but Rob Farley made a comment that may be considered another downside to the COALESCE approach:



                https://sqlblog.org/2011/03/08/t-sql-tuesday-16-this-is-not-the-aggregate-youre-looking-for







                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 11 at 14:21

























                answered Feb 16 '12 at 19:02









                Aaron Bertrand

                207k27361404




                207k27361404












                • Thanks for your input. The concern is relying on an undocumented behavior/feature in a massive production system. Some hotfix down the road, microsoft decides to do things different behind the scenes and this no longer works and breaks things.
                  – J Cooper
                  Feb 16 '12 at 19:07










                • Both can fail if if you want a specific order of the concatenated values. Not the case here but if you do, for xml is the way to go.
                  – Mikael Eriksson
                  Feb 16 '12 at 19:09










                • If your concern is forward compatibility then I would say both approaches introduce the same level of risk. With that in mind FOR XML is, as @Mikael suggests for other reasons, probably the most future-proof method. I realize that's not what you want to hear, but better safe than sorry. It's quite easy to encapsulate this kind of thing - how many different queries are you doing this concatenation for? If it is a lot then perhaps the data model should be a more important concern.
                  – Aaron Bertrand
                  Feb 16 '12 at 19:12












                • I read your article - you sure would be the right guy to answer this question! Yes, I thought FOR XML would be the safe, supported way to go. Actually, Ben-Gan suggests this method in his book. As far as the data model, the data is pulled this way for presentational purposes a good bit - but not my call
                  – J Cooper
                  Feb 17 '12 at 0:54










                • @J Cooper one other comment. If guaranteeing future compatibility (or order) is paramount to strict performance, use a cursor. Anything else is an undocumented trick.
                  – Aaron Bertrand
                  Feb 17 '12 at 12:40


















                • Thanks for your input. The concern is relying on an undocumented behavior/feature in a massive production system. Some hotfix down the road, microsoft decides to do things different behind the scenes and this no longer works and breaks things.
                  – J Cooper
                  Feb 16 '12 at 19:07










                • Both can fail if if you want a specific order of the concatenated values. Not the case here but if you do, for xml is the way to go.
                  – Mikael Eriksson
                  Feb 16 '12 at 19:09










                • If your concern is forward compatibility then I would say both approaches introduce the same level of risk. With that in mind FOR XML is, as @Mikael suggests for other reasons, probably the most future-proof method. I realize that's not what you want to hear, but better safe than sorry. It's quite easy to encapsulate this kind of thing - how many different queries are you doing this concatenation for? If it is a lot then perhaps the data model should be a more important concern.
                  – Aaron Bertrand
                  Feb 16 '12 at 19:12












                • I read your article - you sure would be the right guy to answer this question! Yes, I thought FOR XML would be the safe, supported way to go. Actually, Ben-Gan suggests this method in his book. As far as the data model, the data is pulled this way for presentational purposes a good bit - but not my call
                  – J Cooper
                  Feb 17 '12 at 0:54










                • @J Cooper one other comment. If guaranteeing future compatibility (or order) is paramount to strict performance, use a cursor. Anything else is an undocumented trick.
                  – Aaron Bertrand
                  Feb 17 '12 at 12:40
















                Thanks for your input. The concern is relying on an undocumented behavior/feature in a massive production system. Some hotfix down the road, microsoft decides to do things different behind the scenes and this no longer works and breaks things.
                – J Cooper
                Feb 16 '12 at 19:07




                Thanks for your input. The concern is relying on an undocumented behavior/feature in a massive production system. Some hotfix down the road, microsoft decides to do things different behind the scenes and this no longer works and breaks things.
                – J Cooper
                Feb 16 '12 at 19:07












                Both can fail if if you want a specific order of the concatenated values. Not the case here but if you do, for xml is the way to go.
                – Mikael Eriksson
                Feb 16 '12 at 19:09




                Both can fail if if you want a specific order of the concatenated values. Not the case here but if you do, for xml is the way to go.
                – Mikael Eriksson
                Feb 16 '12 at 19:09












                If your concern is forward compatibility then I would say both approaches introduce the same level of risk. With that in mind FOR XML is, as @Mikael suggests for other reasons, probably the most future-proof method. I realize that's not what you want to hear, but better safe than sorry. It's quite easy to encapsulate this kind of thing - how many different queries are you doing this concatenation for? If it is a lot then perhaps the data model should be a more important concern.
                – Aaron Bertrand
                Feb 16 '12 at 19:12






                If your concern is forward compatibility then I would say both approaches introduce the same level of risk. With that in mind FOR XML is, as @Mikael suggests for other reasons, probably the most future-proof method. I realize that's not what you want to hear, but better safe than sorry. It's quite easy to encapsulate this kind of thing - how many different queries are you doing this concatenation for? If it is a lot then perhaps the data model should be a more important concern.
                – Aaron Bertrand
                Feb 16 '12 at 19:12














                I read your article - you sure would be the right guy to answer this question! Yes, I thought FOR XML would be the safe, supported way to go. Actually, Ben-Gan suggests this method in his book. As far as the data model, the data is pulled this way for presentational purposes a good bit - but not my call
                – J Cooper
                Feb 17 '12 at 0:54




                I read your article - you sure would be the right guy to answer this question! Yes, I thought FOR XML would be the safe, supported way to go. Actually, Ben-Gan suggests this method in his book. As far as the data model, the data is pulled this way for presentational purposes a good bit - but not my call
                – J Cooper
                Feb 17 '12 at 0:54












                @J Cooper one other comment. If guaranteeing future compatibility (or order) is paramount to strict performance, use a cursor. Anything else is an undocumented trick.
                – Aaron Bertrand
                Feb 17 '12 at 12:40




                @J Cooper one other comment. If guaranteeing future compatibility (or order) is paramount to strict performance, use a cursor. Anything else is an undocumented trick.
                – Aaron Bertrand
                Feb 17 '12 at 12:40











                0














                In your example, there is a way to get different results, and that is if NULL values are introduced into the data set. e.g.:



                set nocount on

                declare @test table (value int)

                insert into @test values (10)
                insert into @test values (20)
                insert into @test values (null)
                insert into @test values (40)
                insert into @test values (50)

                DECLARE @output VARCHAR(max);

                -- Approach A
                SET @output = '';

                SELECT @output = @output + CAST(value AS VARCHAR(10)) + ';'
                FROM @test

                print 'Result from A:'
                print isnull(@output, '{null}')

                -- Approach B
                set @output = ''
                SELECT @output = COALESCE(@output + ', ', '') + cast(value as varchar(10))
                from @test

                print 'Result from B:'
                print isnull(@output, '{null}')

                set nocount off


                Approach A will return null, whereas Approach B will return 40, 50






                share|improve this answer


























                  0














                  In your example, there is a way to get different results, and that is if NULL values are introduced into the data set. e.g.:



                  set nocount on

                  declare @test table (value int)

                  insert into @test values (10)
                  insert into @test values (20)
                  insert into @test values (null)
                  insert into @test values (40)
                  insert into @test values (50)

                  DECLARE @output VARCHAR(max);

                  -- Approach A
                  SET @output = '';

                  SELECT @output = @output + CAST(value AS VARCHAR(10)) + ';'
                  FROM @test

                  print 'Result from A:'
                  print isnull(@output, '{null}')

                  -- Approach B
                  set @output = ''
                  SELECT @output = COALESCE(@output + ', ', '') + cast(value as varchar(10))
                  from @test

                  print 'Result from B:'
                  print isnull(@output, '{null}')

                  set nocount off


                  Approach A will return null, whereas Approach B will return 40, 50






                  share|improve this answer
























                    0












                    0








                    0






                    In your example, there is a way to get different results, and that is if NULL values are introduced into the data set. e.g.:



                    set nocount on

                    declare @test table (value int)

                    insert into @test values (10)
                    insert into @test values (20)
                    insert into @test values (null)
                    insert into @test values (40)
                    insert into @test values (50)

                    DECLARE @output VARCHAR(max);

                    -- Approach A
                    SET @output = '';

                    SELECT @output = @output + CAST(value AS VARCHAR(10)) + ';'
                    FROM @test

                    print 'Result from A:'
                    print isnull(@output, '{null}')

                    -- Approach B
                    set @output = ''
                    SELECT @output = COALESCE(@output + ', ', '') + cast(value as varchar(10))
                    from @test

                    print 'Result from B:'
                    print isnull(@output, '{null}')

                    set nocount off


                    Approach A will return null, whereas Approach B will return 40, 50






                    share|improve this answer












                    In your example, there is a way to get different results, and that is if NULL values are introduced into the data set. e.g.:



                    set nocount on

                    declare @test table (value int)

                    insert into @test values (10)
                    insert into @test values (20)
                    insert into @test values (null)
                    insert into @test values (40)
                    insert into @test values (50)

                    DECLARE @output VARCHAR(max);

                    -- Approach A
                    SET @output = '';

                    SELECT @output = @output + CAST(value AS VARCHAR(10)) + ';'
                    FROM @test

                    print 'Result from A:'
                    print isnull(@output, '{null}')

                    -- Approach B
                    set @output = ''
                    SELECT @output = COALESCE(@output + ', ', '') + cast(value as varchar(10))
                    from @test

                    print 'Result from B:'
                    print isnull(@output, '{null}')

                    set nocount off


                    Approach A will return null, whereas Approach B will return 40, 50







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Feb 16 '12 at 20:29









                    CD Jorgensen

                    1,20087




                    1,20087























                        0














                        They work differently, the first example adds an additional character to the end of the output variable, and yes they work because of the same behaviour.



                        The first example will work if your column had been a numeric or date also. It would however only take the first 10 characters of any value in the column. The second example would not cut off the column.



                        There is absolutely no recursive nature of COALESCE.
                        COALESCE is a way of replacing null values with replacement values.



                        EDIT:



                        I should add that i also prefer the second version, because you don't get that extra semicolon, in the end of output implying that more values will follow.






                        share|improve this answer




























                          0














                          They work differently, the first example adds an additional character to the end of the output variable, and yes they work because of the same behaviour.



                          The first example will work if your column had been a numeric or date also. It would however only take the first 10 characters of any value in the column. The second example would not cut off the column.



                          There is absolutely no recursive nature of COALESCE.
                          COALESCE is a way of replacing null values with replacement values.



                          EDIT:



                          I should add that i also prefer the second version, because you don't get that extra semicolon, in the end of output implying that more values will follow.






                          share|improve this answer


























                            0












                            0








                            0






                            They work differently, the first example adds an additional character to the end of the output variable, and yes they work because of the same behaviour.



                            The first example will work if your column had been a numeric or date also. It would however only take the first 10 characters of any value in the column. The second example would not cut off the column.



                            There is absolutely no recursive nature of COALESCE.
                            COALESCE is a way of replacing null values with replacement values.



                            EDIT:



                            I should add that i also prefer the second version, because you don't get that extra semicolon, in the end of output implying that more values will follow.






                            share|improve this answer














                            They work differently, the first example adds an additional character to the end of the output variable, and yes they work because of the same behaviour.



                            The first example will work if your column had been a numeric or date also. It would however only take the first 10 characters of any value in the column. The second example would not cut off the column.



                            There is absolutely no recursive nature of COALESCE.
                            COALESCE is a way of replacing null values with replacement values.



                            EDIT:



                            I should add that i also prefer the second version, because you don't get that extra semicolon, in the end of output implying that more values will follow.







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited Feb 17 '12 at 10:30

























                            answered Feb 17 '12 at 9:54









                            t-clausen.dk

                            35.7k104380




                            35.7k104380






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.





                                Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                Please pay close attention to the following guidance:


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f9317170%2fgroup-string-concatenation-which-approach-if-any-is-any-more-guaranteed%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







                                這個網誌中的熱門文章

                                Xamarin.form Move up view when keyboard appear

                                Post-Redirect-Get with Spring WebFlux and Thymeleaf

                                Anylogic : not able to use stopDelay()