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.

 All Forums
 SQL Server 2000 Forums
 Transact-SQL (2000)
 Help me avoid a cursor!

Author  Topic 

billsox
Yak Posting Veteran

74 Posts

Posted - 2005-02-23 : 13:15:00
Hi --

I have a table like the one shown below...


Category Code
4006 Aug DM
4006 Aug RM
4006 Sep DM
4006 Sep RM
4006 Oct DM
4007 Oct RM
4007 BT112004
4007 BT122004


I want to be able to retrieve the data as such:

Category   TextString
4006 Aug DM,Aug RM,Sep DM,Sep RM,Oct DM
4007 Oct RM,BT112004,BT122004


Keep in mind that I don't know all of the codes at design-time so I can't hard-code a bunch of CASE statements. I'd like to be able to do this without a cursor but I'm thinking that may be my only option. Any suggestions would be appreciated.

Thanks in advance,

Bill

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-02-23 : 13:23:54
Bill,
A bunch of us just got done discussing this very problem. See this topic:

http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=46270





Semper fi, Xerxes, USMC(Ret.)
--------------------------------------------------
Once a Marine ALWAYS a Marine!
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2005-02-23 : 13:33:18
This is an example... though its kindof sloppy. At least it should get you started


Declare @myTable table (a int, b varchar(100), list varchar(100))
insert into @myTable (a,b)
Select 4006, 'Aug DM'
Union Select 4006, 'Aug RM'
Union Select 4006, 'Sep DM'
Union Select 4006, 'Sep RM'
Union Select 4006, 'Oct DM'
Union Select 4007, 'Oct RM'
Union Select 4007, 'BT112004'
Union Select 4007, 'BT122004'

Declare @myList varchar(100),
@lastKey int
Set @lastKey = 0

update @myTable
Set
@myList = case when @lastKey<>a then b else @myList + ', ' + b end,
@lastKey = a,
list = @myList
From @myTable

Select Z.*
From @myTable Z
Inner Join (Select a, listLen = max(len(list)) From @myTable Group By a) Y
On Z.a = Y.a
and len(Z.list) = Y.listLen


Corey

"If the only tool you have is a hammer, the whole world looks like a nail." - Mark Twain
Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-02-23 : 13:38:55
Corey,

He mentioned that the data may be unknown to him. That's why I did this:

SET NOCOUNT ON

DROP TABLE [Whatever]

CREATE TABLE Whatever (ID int NULL, Value varchar(5) NULL)

INSERT INTO Whatever VALUES(1, 'a')
INSERT INTO Whatever VALUES(1, 'b')
INSERT INTO Whatever VALUES(1, 'c')
INSERT INTO Whatever VALUES(2, 'a')
GO
SELECT ID, Value FROM Whatever
GO
declare @Id int
declare @ctr int
declare @value varchar(5)
declare @PrevId int
declare @PrevValue varchar(5)
declare @RowNum int
declare @holder varchar(8000)
declare List cursor for
select ID, Value from Whatever
OPEN List
FETCH NEXT FROM List
INTO @Id, @value
set @RowNum = 0
set @ctr = 0
set @holder = ' '
set @PrevID = 0
set @PrevValue = ' '
WHILE @@FETCH_STATUS = 0
BEGIN
set @RowNum = @RowNum + 1
IF @PrevID <> @Id
BEGIN
set @ctr = @ctr + 1
set @holder = @Value
set @PrevId = @Id
print ' IF =>'+cast(@ctr as char(5))
print ' IF '+cast(@RowNum as char(1)) + ' ID=>' + cast(@Id as char(1))
print ' IF '+cast(@RowNum as char(1)) + ' Value=>' + @Value + ' Holder=>' + @holder
END
ELSE
BEGIN
set @ctr = @ctr + 1

set @PrevValue = @Value
set @holder = ltrim(@holder)+' '+@Value
print ' ELSE =>'+cast(@ctr as char(5))
print ' ELSE '+cast(@RowNum as char(1)) + ' ID=>' + cast(@PrevId as char(1))
print ' ELSE '+cast(@RowNum as char(1)) + ' Value=>' + @Value + ' Holder=>' + @holder
END
--
FETCH NEXT FROM List
INTO @Id, @value

print ' OUTSIDE =>'+cast(@ctr as char(5))
print cast(@RowNum as char(1)) + ' ' + cast(@Id as char(1))+ ' value=>'+@value+' holder=>' +@holder
END
CLOSE List
DEALLOCATE List


and he could make his determination from there.

Bill....just plug this into the SQA and check the messages.


Semper fi,

Xerxes, USMC(Ret.)
------------------------------------------------------
Once a Marine ALWAYS a Marine!
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2005-02-23 : 13:47:38
X - the data is irrelevant. what is important is the key. In his case, the key is the category. My example will produce one row per category. Regardless of how many 'codes' are associated with it.

What does the cursor provide to address: "He mentioned that the data may be unknown to him"?

So.... how bout it bill??? does my example provide what you are looking for?

Corey

"If the only tool you have is a hammer, the whole world looks like a nail." - Mark Twain
Go to Top of Page

X002548
Not Just a Number

15586 Posts

Posted - 2005-02-23 : 13:49:48
Just don't blow out on a size limit....



Brett

8-)
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2005-02-23 : 14:09:00
quote:
Originally posted by X002548

Just don't blow out on a size limit....



Brett

8-)



thats true... I should have mentioned that the varchar sizes are limited in my example. They may have to grow, just hope you don't have two many 'codes' for one 'category'.

Corey

"If the only tool you have is a hammer, the whole world looks like a nail." - Mark Twain
Go to Top of Page

billsox
Yak Posting Veteran

74 Posts

Posted - 2005-02-23 : 14:18:00
Seventhnight,

I like your solution but won't it fail if Category (your Column a) contains a value of zero?

Bill
Go to Top of Page

Seventhnight
Master Smack Fu Yak Hacker

2878 Posts

Posted - 2005-02-23 : 14:29:45
yeah... you could make that whatever you want...

this should not fail

Declare @myList varchar(100),
@lastKey int
Set @lastKey = null

update @myTable
Set
@myList = case when isnull(@lastKey,a+1)<>a then b else @myList + ', ' + b end,
@lastKey = a,
list = @myList
From @myTable


Corey

"If the only tool you have is a hammer, the whole world looks like a nail." - Mark Twain
Go to Top of Page

rockmoose
SQL Natt Alfen

3279 Posts

Posted - 2005-02-23 : 14:55:40
The update technique is truly black magic
Check this alternative: [url]http://sqlteam.com/item.asp?ItemID=2368[/url]
You can wrap that technique in an udf.
Just so You have options...

rockmoose
Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-02-25 : 12:11:15
quote:
Originally posted by rockmoose

The update technique is truly black magic
Check this alternative: [url]http://sqlteam.com/item.asp?ItemID=2368[/url]
You can wrap that technique in an udf.
Just so You have options...

rockmoose



Waht IS this 'magic' you speak of?

Semper fi,

XERXES, USMC(Ret.)
------------------------------------------------------
The Marine Corps taught me everything but SQL!
Go to Top of Page

rockmoose
SQL Natt Alfen

3279 Posts

Posted - 2005-02-25 : 15:18:59
It's an advanced technique that is not taught in class, and afaik it is not known/used by many people.
update @myTable --(table variable in corey's example, but could be regular or temporary table)
Set
@myList = case when @lastKey<>a then b else @myList + ', ' + b end, --<--here a new value is assigned/appended to @list for every row in the table
@lastKey = a,
list = @myList --<--then this column is updated to the value in @list
From @myTable
Is this documented anywhere? dont think so..., part of SQL standard?, don't think so...,
feature?, or just "magic"???



rockmoose
Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-02-25 : 15:54:21
quote:
Originally posted by rockmoose

It's an advanced technique that is not taught in class, and afaik it is not known/used by many people.
update @myTable --(table variable in corey's example, but could be regular or temporary table)
Set
@myList = case when @lastKey<>a then b else @myList + ', ' + b end, --<--here a new value is assigned/appended to @list for every row in the table
@lastKey = a,
list = @myList --<--then this column is updated to the value in @list
From @myTable
Is this documented anywhere? dont think so..., part of SQL standard?, don't think so...,
feature?, or just "magic"???



rockmoose



I learn so many NEW and INTERESTING things from you, 'Moose!

That is sooooo cool

Thank you soooo much!

Semper fi,

XERXES, USMC(Ret.)
------------------------------------------------------
The Marine Corps taught me everything but SQL!
Go to Top of Page

tkeith
Starting Member

9 Posts

Posted - 2005-02-25 : 17:12:33
I thought the technique was pretty sweet as well. Kudos to the wizards that came up with this "magic" . I'm sure it will come in handy in the future.
Go to Top of Page

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2005-02-25 : 20:12:57
acctually if u read carefuly about update in bol you find this:
quote:

@variable
Is a declared variable that is set to the value returned by expression.

SET @variable = column = expression sets the variable to the same value as the column. This differs from SET @variable = column, column = expression, which sets the variable to the pre-update value of the column.



Go with the flow & have fun! Else fight the flow
Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-02-25 : 21:05:55
quote:
Originally posted by spirit1

acctually if u read carefuly about update in bol you find this:
quote:

@variable
Is a declared variable that is set to the value returned by expression.

SET @variable = column = expression sets the variable to the same value as the column. This differs from SET @variable = column, column = expression, which sets the variable to the pre-update value of the column.



OK, Mladen, you're sapping my sense of awe and wonder

Hey, just kidding....nice point, though. I think I'll peruse the online tome and go BOL-ing! (Get it?)

Now where did I put my BOL-ing bag?
Go with the flow & have fun! Else fight the flow



Semper fi,

XERXES, USMC(Ret.)
------------------------------------------------------
The Marine Corps taught me everything but SQL!
Go to Top of Page

spirit1
Cybernetic Yak Master

11752 Posts

Posted - 2005-02-26 : 08:55:10
go BOL-ing... hehe. nice one!!
don't let the BOL-ing cd drop on your foot... all that weight you know...you might get hurt

Go with the flow & have fun! Else fight the flow
Go to Top of Page

Xerxes
Aged Yak Warrior

666 Posts

Posted - 2005-02-27 : 18:48:42
quote:
Originally posted by spirit1

go BOL-ing... hehe. nice one!!
don't let the BOL-ing cd drop on your foot... all that weight you know...you might get hurt

Go with the flow & have fun! Else fight the flow



Mladen, glad you liked that one!

Hey, I think I got a strike!

Semper fi,

XERXES, USMC(Ret.)
------------------------------------------------------
The Marine Corps taught me everything but SQL!
Go to Top of Page
   

- Advertisement -