Wrox Programmer Forums
|
SQL Server 2000 General discussion of Microsoft SQL Server -- for topics that don't fit in one of the more specific SQL Server forums. version 2000 only. There's a new forum for SQL Server 2005.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the SQL Server 2000 section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old November 18th, 2003, 02:33 AM
Authorized User
 
Join Date: Nov 2003
Posts: 42
Thanks: 0
Thanked 0 Times in 0 Posts
Default Concatenating like records

I got records like this:

ColumnA ColumnB
---------- -----------------------
aa This is
aa Thursday morning
bb Friday morning
cc This is
cc Saturday morning

Is it possible to write a select query to return rows like the following:
ColumnA ColumnB
---------- ------------------------------
aa This is Thursday morning
bb Friday morning
cc This is Saturday morning

Kindly help. TIA

Code for creating/insertion:
create table #temp1 (a char(10), b varchar(4000))

insert into #temp1 values ('aa', 'This is ')
insert into #temp1 values ('aa', 'Thursday morning')
insert into #temp1 values ('bb', 'Friday morning')
insert into #temp1 values ('cc', 'This is ')
insert into #temp1 values ('cc', 'Saturday morning')

 
Old November 18th, 2003, 03:27 AM
Authorized User
 
Join Date: Jun 2003
Posts: 77
Thanks: 0
Thanked 0 Times in 0 Posts
Default

As far as i know, there are two ways to accomplish this:
- using a cursor (i hate cursors). this works in SQL Server 2000 or 7, maybe even earlier;
- using a user-defined function (udf). This works in SQL Server 2000 only.

Here is the solution with the udf:

Code:
create function dbo.fnTmp (
@ColumnAVal nvarchar(50)
) returns nvarchar(100)
as
begin
    declare @RetVal nvarchar(100)

    select @RetVal = isnull(@RetVal, '') + ColumnB
    from tmp
    where ColumnA = @ColumnAVal

    return @RetVal
end

go

select ColumnA, dbo.fnTmp(ColumnA)
from tmp
group by ColumnA
Above, I'm using a 'normal' table called tmp for the data. I don't know if it will work with a temporary table (#temp). That's for you to figure out.

Hope this helps,

defiant.
 
Old November 18th, 2003, 07:35 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 839
Thanks: 0
Thanked 1 Time in 1 Post
Default

Note that the "string aggregation" being done in the UDF here is an 'undocumented feature' of SQL Server. It is undocumented because there is no way to guarantee the order in which the strings in the group are returned. This means you cannot always depend on the resultant string (e.g. for Group 'aa') being "This is Thursday morning" - it could just as easily be "Thursday morning This is". It might be one way on one server one day and the other way on a different server the next.

Having said that, the reality is that it is fairly predictable as long as the operation is "simple" - that is, there are no involved JOINS or ORDER BYs or other similar operations. In the straightforward case the order of concatenation will be in the order of the clustered index.

If you want to always guarantee the order of concatenation, you must use a cursor, I'm afraid.


Jeff Mason
Custom Apps, Inc.
www.custom-apps.com
 
Old November 18th, 2003, 08:09 AM
Authorized User
 
Join Date: Jun 2003
Posts: 77
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Knowing this now, I recommend using a cursor.

defiant.
 
Old November 18th, 2003, 08:19 AM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 132
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Could you give me a quick explantion of why/how cursors fix the ordering, please.

PS disregard previous mailed reply, I meant to hit backspace and delete everything, not return to send it!


There are two secrets to success in this world:
1. Never tell everything you know
 
Old November 18th, 2003, 05:56 PM
Friend of Wrox
 
Join Date: Oct 2003
Posts: 336
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to alyeng2000
Default

instead of cursors
it is possible to put a third col with concatination order so order is done then concatenation like follows


create table temp1 (a char(10), b varchar(4000),c int)

insert into temp1 values ('aa', 'This is ',1)
insert into temp1 values ('aa', 'Thursday morning',2)
insert into temp1 values ('bb', 'Friday morning',1)
insert into temp1 values ('cc', 'This is ',2)
insert into temp1 values ('cc', 'Saturday morning',1)

create function fnTmp (
@ColumnAVal nvarchar(50)
) returns nvarchar(100)
as
begin
    declare @RetVal nvarchar(100)

    select @RetVal = isnull(@RetVal, '') + b
    from temp1
    where a = @ColumnAVal
    order by c --- here is the change

    return @RetVal
end

select a, fnTmp(a)
from temp1
group by a

Ahmed Ali
Software Developer
 
Old November 18th, 2003, 08:26 PM
Friend of Wrox
 
Join Date: Jun 2003
Posts: 839
Thanks: 0
Thanked 1 Time in 1 Post
Default

Adding the ORDER BY clause will not (necessarily) work.

The reason is that an ORDER BY clause is the very last bit of processing which is done when a SELECT statement is executed. That is, the entire resultset as specified by the SELECT statement is constructed, and then it is sorted.

So, the string aggregation happens before the ORDER BY clause is even executed. There is no way to specify the order in which rows are processed "inside" the execution of the SELECT statement, and that is why this approach won't work. Of course, it may look like it works, and that is why this is somewhat of an insidious problem (and why it is 'officially' undocumented behavior).

alyeng2000 correctly points out that an ordering column (within the group) is needed, though. The OP's table design only lists two columns, thus there is no way to specify the ordering of the individual strings of the group's rows, even if you do use a cursor.

If such an ordering column existed, then defining a cursor would be along the lines of:
Code:
DECLARE mycursor CURSOR FOR
    SELECT ColumnA, ColumnB, OrderingCol
    FROM yourtable
    GROUP BY ColumnA, ColumnB, OrderingCol
    ORDER BY ColumnA, OrderingCol
You would then process this cursor sequentially, one row at a time (which is what cursors do), "watch" when the grouping column changes, and construct the aggregate by concatenating the string column when the grouping column is the same as the prior row, and resetting the variable to a zero length string when the grouping value does change. You also have to put the intermediate results somewhere, presumably into a temporary table, then SELECT that table as a resultset back to the client.

This whole process can be a bit of a pain, and probably not very efficient, since TSQL is not the most efficient procedural language, so this may very well be best handled at the client for all but the simplest cases...

Jeff Mason
Custom Apps, Inc.
www.custom-apps.com
 
Old November 19th, 2003, 04:00 AM
Authorized User
 
Join Date: Jun 2003
Posts: 77
Thanks: 0
Thanked 0 Times in 0 Posts
Default

I agree with Jeff Mason. If the string concatenation inside a group must be done in a certain order, then you a cursor with an ORDER BY clause is the only 100% working approach.

defiant.
 
Old March 28th, 2007, 10:52 PM
msa msa is offline
Registered User
 
Join Date: Mar 2007
Posts: 3
Thanks: 0
Thanked 0 Times in 0 Posts
Default

hi everybody,ive got the same problem here.i am a newby in sql.
supposed i have this records

Table1
StudId StudentName
1 AB
1 BC
2 FG
3 ED
2 MN

Table 2
StudID
1
1
2
3
2

i need to have a condition where table2.StudID is equal to Table1.StudID then the output will look like this


StudID StudName
1 AB,BC
2 FG,MN
3 ED

hope to hear from anyone..thanks for the help in advance
 
Old March 28th, 2007, 11:47 PM
Friend of Wrox
 
Join Date: May 2006
Posts: 246
Thanks: 0
Thanked 0 Times in 0 Posts
Default

How can you tell which of the AA records to fetch first?







Similar Threads
Thread Thread Starter Forum Replies Last Post
concatenating records rashi Access VBA 9 November 6th, 2008 05:07 PM
Concatenating strings of code sassora Word VBA 1 March 31st, 2006 02:39 PM
Concatenating many XML files srivalli9 XML 4 March 30th, 2006 03:05 AM
Concatenating column values arnabghosh Access 1 September 21st, 2005 06:45 AM
concatenating arrays allee_man BOOK: Beginning PHP4/PHP 5 ISBN: 978-0-7645-4364-7; v5 ISBN: 978-0-7645-5783-5 0 August 19th, 2005 08:55 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.