Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase 12»»

Proper way to concatenate values in a set from 1 column Expand / Collapse
Author
Message
Posted Wednesday, January 30, 2013 9:40 AM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 6:43 AM
Points: 2,612, Visits: 3,123
I was asked today to look at a colleague's code on concatenating values returned from 1 column. He said that they have always used the method illustrated below:
create table #temp (data varchar(32))

declare @sql varchar(512)

insert #temp
select 'a'
union all
select 'b'
union all
select 'c'
union all
select 'd'
union all
select 'e'
union all
select 'e'
union all
select 'f'

select @sql = ''

select @sql = @sql + data from #temp

select @sql

drop table #temp

I understand what is happening here, but believe that this could change at any time in a future version. In my opinion the statement "select @sql = @sql + data from #temp" should fail with an error something like "more than 1 value returned for column data" or something of that nature. Am I wrong?


Thanks,

Jared
SQL Know-It-All

How to post data/code on a forum to get the best help - Jeff Moden
Post #1413690
Posted Wednesday, January 30, 2013 10:00 AM
Ten Centuries

Ten CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen CenturiesTen Centuries

Group: General Forum Members
Last Login: Today @ 8:56 AM
Points: 1,320, Visits: 1,773
No, no syntax errors per se, but that method's not guaranteed to work safely either.

SQL DBA,SQL Server MVP('07, '08, '09)
One man with courage makes a majority. Andrew Jackson
Post #1413699
Posted Wednesday, January 30, 2013 10:59 AM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 6:43 AM
Points: 2,612, Visits: 3,123
ScottPletcher (1/30/2013)
No, no syntax errors per se, but that method's not guaranteed to work safely either.
Thanks Scott! Now, in a second question... What do you think is the best way to do the above, but eliminate duplicate values in the final result. i.e. final result would be 'abcdef' instead of 'abcdeef'

We are trying to come up with a good way to do it without a subquery or CTE, but I don't think it an be done without one.


Thanks,

Jared
SQL Know-It-All

How to post data/code on a forum to get the best help - Jeff Moden
Post #1413722
Posted Wednesday, January 30, 2013 11:21 AM


SSC Veteran

SSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC VeteranSSC Veteran

Group: General Forum Members
Last Login: Wednesday, May 08, 2013 10:24 AM
Points: 237, Visits: 413
SELECT STUFF(( SELECT ''+A.data FROM (SELECT DISTINCT TOP 100 PERCENT data FROM #temp ORDER BY data) A
FOR XML PATH ('')),1,1,'')

Would that not work? I have found that to be effective. I mean, there is a sub query, but really, its pretty darn efficient. I think I have seen timings (cant find them atm though) and it beats using a CTE.
Post #1413728
Posted Wednesday, January 30, 2013 11:42 AM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 6:43 AM
Points: 2,612, Visits: 3,123
DiverKas (1/30/2013)
SELECT STUFF(( SELECT ''+A.data FROM (SELECT DISTINCT TOP 100 PERCENT data FROM #temp ORDER BY data) A
FOR XML PATH ('')),1,1,'')

Would that not work? I have found that to be effective. I mean, there is a sub query, but really, its pretty darn efficient. I think I have seen timings (cant find them atm though) and it beats using a CTE.
Almost! change the second 1 to a 0 to keep the 'a' in the string.


Thanks,

Jared
SQL Know-It-All

How to post data/code on a forum to get the best help - Jeff Moden
Post #1413732
Posted Wednesday, January 30, 2013 9:11 PM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 3:20 AM
Points: 2,341, Visits: 3,175
ScottPletcher (1/30/2013)
No, no syntax errors per se, but that method's not guaranteed to work safely either.


Scott - Can you explain this?

I understand that ordering may be an issue. Anything else?



No loops! No CURSORs! No RBAR! Hoo-uh!

INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?

Need to UNPIVOT? Why not CROSS APPLY VALUES instead?
Since random numbers are too important to be left to chance, let's generate some!
Are you too recursively challenged?
Splitting strings based on patterns can be fast!
Post #1413834
Posted Wednesday, January 30, 2013 9:15 PM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 3:20 AM
Points: 2,341, Visits: 3,175
SQLKnowItAll (1/30/2013)
DiverKas (1/30/2013)
SELECT STUFF(( SELECT ''+A.data FROM (SELECT DISTINCT TOP 100 PERCENT data FROM #temp ORDER BY data) A
FOR XML PATH ('')),1,1,'')

Would that not work? I have found that to be effective. I mean, there is a sub query, but really, its pretty darn efficient. I think I have seen timings (cant find them atm though) and it beats using a CTE.
Almost! change the second 1 to a 0 to keep the 'a' in the string.


That's because there's no need for STUFF:

SELECT TOP 1 (
SELECT DISTINCT data + ''
FROM #temp
FOR XML PATH(''))
FROM #temp





No loops! No CURSORs! No RBAR! Hoo-uh!

INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?

Need to UNPIVOT? Why not CROSS APPLY VALUES instead?
Since random numbers are too important to be left to chance, let's generate some!
Are you too recursively challenged?
Splitting strings based on patterns can be fast!
Post #1413836
Posted Thursday, January 31, 2013 1:35 AM


SSCertifiable

SSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiableSSCertifiable

Group: General Forum Members
Last Login: Today @ 7:20 AM
Points: 5,613, Visits: 10,980
dwain.c (1/30/2013)
ScottPletcher (1/30/2013)
No, no syntax errors per se, but that method's not guaranteed to work safely either.


Scott - Can you explain this?

I understand that ordering may be an issue. Anything else?


The same method is used for dynamic crosstabs explained in a little more detail here. Until someone posts a problem with it I'm going to assume the method is guaranteed to work because Jeff's articles have a very high read count (nearly 38,000 folks have read the Crosstabs and Pivots article). That's quite a lot of ad hoc testing.
Having said that, I read somewhere on ssc that the method worked by accident rather than by design and may not work in a future release of the product. I'm not holding my breath.


“Write the query the simplest way. If through testing it becomes clear that the performance is inadequate, consider alternative query forms.” - Gail Shaw

For fast, accurate and documented assistance in answering your questions, please read this article.
Understanding and using APPLY, (I) and (II) Paul White
Hidden RBAR: Triangular Joins / The "Numbers" or "Tally" Table: What it is and how it replaces a loop Jeff Moden
Exploring Recursive CTEs by Example Dwain Camps
Post #1413896
Posted Thursday, January 31, 2013 4:44 AM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 3:20 AM
Points: 2,341, Visits: 3,175
ChrisM@Work (1/31/2013)
dwain.c (1/30/2013)
ScottPletcher (1/30/2013)
No, no syntax errors per se, but that method's not guaranteed to work safely either.


Scott - Can you explain this?

I understand that ordering may be an issue. Anything else?


The same method is used for dynamic crosstabs explained in a little more detail here. Until someone posts a problem with it I'm going to assume the method is guaranteed to work because Jeff's articles have a very high read count (nearly 38,000 folks have read the Crosstabs and Pivots article). That's quite a lot of ad hoc testing.
Having said that, I read somewhere on ssc that the method worked by accident rather than by design and may not work in a future release of the product. I'm not holding my breath.


Every self-proclaimed SQL guru with a blog has an example of this on their sites. Never have I heard a whisper about issues with it, but then that doesn't say much given the general quality of those sources.

If I were Microsoft, my feeling would be why tinker with something that works. Of course, making it not work could be a side effect of doing something else.

I must confess though to always having my suspicions about it just because it doesn't look like something that was intended as a SQL feature (and I'm not sure why I can say this other than my gut rumbling in disquiet). So far, I haven't been able to not make it work when I've tried to use it. Although I have seen some instabilities related to ordering which I was able to overcome. Actually my biggest issue with it is that it's pretty useless if the concat process has to be applied to split record groups.

Can't wait to hear what Scott might have to say about it.



No loops! No CURSORs! No RBAR! Hoo-uh!

INDEXing a poor-performing query is like putting sugar on cat food. Yeah, it probably tastes better but are you sure you want to eat it?

Need to UNPIVOT? Why not CROSS APPLY VALUES instead?
Since random numbers are too important to be left to chance, let's generate some!
Are you too recursively challenged?
Splitting strings based on patterns can be fast!
Post #1413995
Posted Thursday, January 31, 2013 6:38 AM


SSCrazy

SSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazySSCrazy

Group: General Forum Members
Last Login: Today @ 6:43 AM
Points: 2,612, Visits: 3,123
Here's my issue...

1. It is not syntactically correct, so it should not work. Just because it solves a problem that many of us have does not make it a good thing. It shouldn't even parse.

2. However!!! SQL 2012 solves this problem with new window functions, so I'm not going to complain too much...



Thanks,

Jared
SQL Know-It-All

How to post data/code on a forum to get the best help - Jeff Moden
Post #1414088
« Prev Topic | Next Topic »

Add to briefcase 12»»

Permissions Expand / Collapse