Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
terrence_chan99
Starting Member
12 Posts |
Posted - 2007-01-08 : 17:36:50
|
| Here is my example.dataID CommentID Comments1 1 'app'1 2 'le'2 1 'or'2 2 'an' 2 3 'ge'3 1 'banana'results want to get1 apple2 orange3 bananaI was thinking to using the PIVOT, but as the number of row is unknown, I think it can't be use.any help is appreciate! |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-01-08 : 17:48:15
|
| [code]-- prepare test datadeclare @t table (id tinyint, commentid tinyint, comments varchar(6))insert @tselect 1, 1, 'app' union allselect 1, 2, 'le' union allselect 2, 1, 'or' union allselect 2, 2, 'an' union allselect 2, 3, 'ge' union allselect 3, 1, 'banana'-- show the dataselect id, max(case when commentid = 1 then comments else '' end) + max(case when commentid = 2 then comments else '' end) + max(case when commentid = 3 then comments else '' end)from @tgroup by idorder by id[/code]Peter LarssonHelsingborg, Sweden |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-01-08 : 17:49:38
|
| Since SQL Server is rowbased, the number of rows does not matter!If you are referring to the number of columns, just add more MAX(CASE rows !If commentid is not found, an empty string is added to the string. If you think 20 is max, add 20 rows.Peter LarssonHelsingborg, Sweden |
 |
|
|
terrence_chan99
Starting Member
12 Posts |
Posted - 2007-01-08 : 18:01:40
|
| Peso,Thanks for the reply. It works. however, the drawback is the limit of comment. Let say you add 20 max statement, it will not work from 21. If I add more max statement, it will create a lot of empty string.Is there a way to handle any number of comments?Thanks! |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-01-08 : 18:34:25
|
Yes. By using dynamic SQL with crosstab/pivot table.Or, using an UDF.CREATE FUNCTION dbo.fnConc( @ID INT)RETURNS VARCHAR(8000)ASBEGIN declare @s varchar(8000) select @s = isnull(@s + comments, comments) from test where id = @ID order by commentid return @send Then all the rest is a breaze-- prepare test datacreate table test (id tinyint, commentid tinyint, comments varchar(6))insert testselect 1, 1, 'app' union allselect 1, 2, 'le' union allselect 2, 1, 'or' union allselect 2, 2, 'an' union allselect 2, 3, 'ge' union allselect 3, 1, 'banana'-- show the dataselect distinct id, dbo.fnConc(id) as commentfrom testorder by iddrop table test Please remember that there is a limit of 8000 chars when concating string this way.Peter LarssonHelsingborg, Sweden |
 |
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2007-01-08 : 18:42:05
|
Here are some sql2005 ways too:create table #x(ID int, CommentID int, Comments varchar(50))insert #x select 1, 1, 'app'union all select 1, 2, 'le'union all select 2, 1, 'or'union all select 2, 2, 'an'union all select 2, 3, 'ge'union all select 3, 1, 'banana'union all select 3, 3, '2banana'select ID ,(select Comments as [text()] from #x x2 where x1.ID = x2.ID order by x2.CommentID for xml path('')) as txtfrom #x x1group by IDselect ID ,txtfrom #x x1 cross apply(select Comments as [text()] from #x x2 where x1.ID = x2.ID order by x2.CommentID for xml path(''))x(txt)group by ID,txt-- the ordercte is just to get rid of any possible gaps in CommentID seq.;with ordercte(ID, CommentID, Comments)as( select ID, rank() over(partition by ID order by CommentID) as CommentID, Comments from #x),recursivecte(ID, CommentID, Comments)as( select ID, CommentID, cast(Comments as varchar(max)) from ordercte where CommentID = 1 union all select ordercte.ID, ordercte.CommentID, cast(recursivecte.Comments+ordercte.Comments as varchar(max)) from ordercte join recursivecte on ordercte.ID = recursivecte.ID and ordercte.CommentID = recursivecte.CommentID+1)select ID, Commentsfrom( select *,rank() over(partition by ID order by CommentID desc) as lst from recursivecte) xwhere lst=1select * from #xdrop table #xrockmoose |
 |
|
|
SwePeso
Patron Saint of Lost Yaks
30421 Posts |
Posted - 2007-01-08 : 18:45:36
|
| Rank() ?Is rank faster than row_number?Peter LarssonHelsingborg, Sweden |
 |
|
|
rockmoose
SQL Natt Alfen
3279 Posts |
Posted - 2007-01-08 : 18:54:02
|
They serve the same purpose here, and I could use row_number().I guess it was just that rank() slipped in first, by chance. I can't say anything about performance, but row_number surely should be more simplistic.Will have to test on real data to see any diff..rockmoose |
 |
|
|
|
|
|
|
|