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 |
livezone
Starting Member
10 Posts |
Posted - 2011-07-20 : 15:23:23
|
When I am using order by caluse with string concatenation it only gives me the last row.select @x= Coalesce(@x + '|' , '') + data from table order by col1Without order by all the data shown but it is not ordered.Below is the link from Microsoft, Does this behaviour still exists in SQL 2005?[url]http://support.microsoft.com/kb/287515/en-us[/url] |
|
Vinnie881
Master Smack Fu Yak Hacker
1231 Posts |
Posted - 2011-07-20 : 16:01:33
|
I tried on sql 2005 and there were no issues.declare @a as varchar(4000)select @a = Coalesce(@a + '|' , '') + col1from mytableorder by col2 descselect @a Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881 |
 |
|
livezone
Starting Member
10 Posts |
Posted - 2011-07-20 : 16:38:24
|
It does works but not all the time. I got last row when using order and all rows when not using order by?Try the following codeDECLARE @Mon varchar(20)DECLARE @Tue varchar(20)DECLARE @Wed varchar(20)DECLARE @Thu varchar(20)DECLARE @Fri varchar(20)DECLARE @Sat varchar(20)DECLARE @Sun varchar(20)DECLARE @StoreHours varchar(500)Declare @counter_table table (Idx smallint,[Name] varchar(10) ,Hours varchar(30) ) Set @Mon = '9:30am-7:00pm'Set @Tue = '9:30am-7:00pm'Set @Wed = '10:00am-6:00pm'Set @Thu = '9:30am-7:00pm'Set @Fri = '9:30am-7:00pm'Insert into @counter_table Select 2 , 'Mon' , @MonUnion allSelect 3 , 'Tue' , @TueUnion allSelect 4 , 'Wed' , @WedUnion allSelect 5 , 'Thu' , @ThuUnion allSelect 6 , 'Fri' , @Fri;with Data1 as( select hours, str(idx, 1) + [name] as idxname, row_number() over(order by hours, idx) - row_number() over(order by idx) as grp from @counter_table) ,Data2 as (select ltrim(min(idxname)) as mn, Case When min(idxname) = max(idxname) Then Stuff(min(idxname),1,1,'') else stuff(min(idxname),1,1,'') + '-' + stuff(max(idxname),1,1,'') end + ':' + hours as StoreHoursfrom Data1group by hours, grp )Select *--@StoreHours = Coalesce(@StoreHours + '<br>' , '') + StoreHoursfrom Data2 order by mn;select @StoreHoursIf I run this code it gives me this output2Mon Mon-Tue:9:30am-7:00pm4Wed Wed:10:00am-6:00pm5Thu Thu-Fri:9:30am-7:00pmIf uncomment the below line --@StoreHours = Coalesce(@StoreHours + '<br>' , '') + StoreHours@StoreHours will only contain last row. ThanksShafiq |
 |
|
TG
Master Smack Fu Yak Hacker
6065 Posts |
Posted - 2011-07-20 : 17:15:50
|
strange problem. Once I corrected your coalesce:@StoreHours = Coalesce(@StoreHours + '<br>' + StoreHours, StoreHours)I noticed a couple things:If I comment out the ORDER BY it works.If I select into a #temp table and run your final statement from the #temp table then it also works with and without the order by.Something about calling from the serialized CTEs is breaking it...still playingEDIT:I see your coalesce will variation also works - sorry about that.EDIT2:I finally also saw that you originally noticed the same thing with the order by. Man, I'm slow today :(Be One with the OptimizerTG |
 |
|
Vinnie881
Master Smack Fu Yak Hacker
1231 Posts |
Posted - 2011-07-21 : 12:57:51
|
If you must use the cte, just put all results into a table before you runDECLARE @Mon varchar(20)DECLARE @Tue varchar(20)DECLARE @Wed varchar(20)DECLARE @Thu varchar(20)DECLARE @Fri varchar(20)DECLARE @Sat varchar(20)DECLARE @Sun varchar(20)DECLARE @StoreHours varchar(500)Declare @counter_table table (Idx smallint,[Name] varchar(10) ,Hours varchar(30) ) Set @Mon = '9:30am-7:00pm'Set @Tue = '9:30am-7:00pm'Set @Wed = '10:00am-6:00pm'Set @Thu = '9:30am-7:00pm'Set @Fri = '9:30am-7:00pm'Insert into @counter_table Select 2 , 'Mon' , @MonUnion allSelect 3 , 'Tue' , @TueUnion allSelect 4 , 'Wed' , @WedUnion allSelect 5 , 'Thu' , @ThuUnion allSelect 6 , 'Fri' , @Fri;with Data1 as( select hours, str(idx, 1) + [name] as idxname, row_number() over(order by hours, idx) - row_number() over(order by idx) as grp from @counter_table) ,Data2 as (select ltrim(min(idxname)) as mn, Case When min(idxname) = max(idxname) Then Stuff(min(idxname),1,1,'') else stuff(min(idxname),1,1,'') + '-' + stuff(max(idxname),1,1,'') end + ':' + hours as StoreHoursfrom Data1group by hours, grp )Select *into #tmpfrom Data2 order by mn;select @StoreHours = coalesce(@StoreHours + '<br>' , '') + StoreHoursfrom #tmpdrop table #tmpselect @StoreHours Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881 |
 |
|
livezone
Starting Member
10 Posts |
Posted - 2011-07-21 : 13:23:00
|
But why this problem exists with CTE? |
 |
|
Vinnie881
Master Smack Fu Yak Hacker
1231 Posts |
Posted - 2011-07-21 : 15:26:21
|
I do not know why there is a issue with a CTE, but I would personally not use a CTE, this method should significantly outperform the method you illustrated on large data sets, and a clustered index has been proven pretty reliable used in this fashion.DECLARE @Mon varchar(20)DECLARE @Tue varchar(20)DECLARE @Wed varchar(20)DECLARE @Thu varchar(20)DECLARE @Fri varchar(20)DECLARE @Sat varchar(20)DECLARE @Sun varchar(20)DECLARE @StoreHours varchar(500)DECLARE @count intDeclare @counter_table table (Idx smallint,[Name] varchar(10) ,Hours varchar(30) ) Declare @counter_tablewrk table (Idx smallint primary key,[Name] varchar(10) ,Hours varchar(30) ,usethis bit,running varchar(2000),mygroup int,mygroupcount int) Set @Mon = '9:30am-7:00pm'Set @Tue = '9:30am-7:00pm'Set @Wed = '10:00am-6:00pm'Set @Thu = '9:30am-7:00pm'Set @Fri = '9:30am-7:00pm'Insert into @counter_table Select 2 , 'Mon' , @MonUnion allSelect 3 , 'Tue' , @TueUnion allSelect 4 , 'Wed' , @WedUnion allSelect 5 , 'Thu' , @ThuUnion allSelect 6 , 'Fri' , @Friinsert into @counter_tablewrk(Idx,[Name],Hours)select Idx,[Name],Hoursfrom @counter_tableorder by idxdeclare @holder varchar(2000),@anchor int,@lasttime varchar(20),@minday varchar(20),@mygroup int,@mygroupcount intset @mygroup =0set @mygroupcount =0 update aset @holder = running = case when @lasttime is null then [name] + ':' + hours when @lasttime = hours then @minday + '-' + [name] + ':' + hours else [name] + ':' + hours --this is a use end ,@mygroup = mygroup = case when @lasttime = hours then @mygroup when @lasttime is null then @mygroup else @mygroup + 1 end ,@mygroupcount = mygroupcount = case when @lasttime = hours then @mygroupcount + 1 when @lasttime is null then @mygroupcount + 1 else 1 end ,@minday = case when @lasttime = hours then @minday else [name] end,@lasttime = hours,@anchor = idxfrom@counter_tablewrk aselect runningfrom(select row_number() over (partition by mygroup order by mygroupcount desc) as rowid,* from @counter_tablewrk a) aawhere aa.rowid = 1 Success is 10% Intelligence, 70% Determination, and 22% Stupidity.\_/ _/ _/\_/ _/\_/ _/ _/- 881 |
 |
|
|
|
|
|
|