Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Concatenation Failure

Status
Not open for further replies.

briangriffin

Programmer
Nov 6, 2008
878
0
0
US
I've read the FAQ and other posts regarding concatenating fields into a long string, but something isn't quite right when I try. Using the AdventureWorks db, I want a listing of each sales territory and then one field listing each salesperson in that territory:

Code:
declare @v_sales table

	(territoryID int ,
	territory varchar(15),
	salesmen varchar(255))
	

insert into @v_sales (territoryID,territory, salesmen)
select TerritoryID, Name,''
from  Sales.SalesTerritory
order by 1



declare @v_salesmen table
	(territoryID int,
	salesperson varchar(40),
	sales numeric(20,2))

insert into @v_salesmen
select     
c.TerritoryID,
d.FirstName + ' ' + d.LastName, 
a.SalesYTD
from Sales.SalesPerson a INNER JOIN HumanResources.Employee b
	on b.EmployeeID = a.SalesPersonID 
LEFT OUTER JOIN Sales.SalesTerritory c 
	on c.TerritoryID = a.TerritoryID 
INNER JOIN Person.Contact AS d 
	on d.ContactID = b.ContactID
order by 1 

Declare @min int, @max int
Select @min = 1, @max = Max(TerritoryID)
From @v_sales


While @min <= @max
 Begin
   Update @v_sales
     Set salesmen = salesmen + b.salesperson + ' '
   From @v_sales a  inner join @v_salesmen b
     ON a.territoryID = b.territoryID
   Where a.territoryID = @min

   Select @min = @min + 1
 End

select * from @v_sales

I'm getting a list of territories, but only one salesman from each - where did I go wrong? (I'm not concerned with the sales total field right now).

Thanks.
 
I think you're going about it the wrong way - it should be far simpler by grouping. Here's a simple example:
Code:
SELECT
    TerritoryID,
    FirstName,
    LastName
FROM
    Sales.SalesPerson
GROUP BY
    TerritoryID,
    FirstName,
    LastName

Or if you really want to concatenate the SalesPerson records into 1 string then you could do it more efficiently with a self join.
 
It's hard to say, but I think your problem is concerning nulls. When you concatenate a null to a string, the result is NULL. Try this:

Code:
   Update @v_sales
     Set salesmen = salesmen + b.salesperson + ' '
   From @v_sales a  inner join @v_salesmen b
     ON a.territoryID = b.territoryID
   Where a.territoryID = @min
[!]         And b.salesperson is not null[/!]

-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Thanks to you both - I think the problem was related to the nulls. I ended up using the coalesce function in 2005:


Code:
declare @v_salesmen table
	(territoryID int,
	salesperson varchar(40))

insert into @v_salesmen
select     
case when c.TerritoryID is null then 0 else c.TerritoryID end,
d.FirstName + ' ' + d.LastName
from Sales.SalesPerson a inner join HumanResources.Employee b
	on b.EmployeeID = a.SalesPersonID 
left outer join Sales.SalesTerritory c 
	on c.TerritoryID = a.TerritoryID 
inner join Person.Contact AS d 
	on d.ContactID = b.ContactID
order by 1 


declare @v_counter int, @v_max int
select @v_counter = min(territoryID) from @v_salesmen
select @v_max = max(territoryID) from @v_salesmen

declare @v_salestable table 
				(territoryID int,
				salesmen varchar(1000))

while @v_counter <= @v_max
BEGIN
declare @v_saleslist varchar(8000)
set @v_saleslist = ''
select @v_saleslist = coalesce(@v_saleslist + ', ','') + salesperson
from @v_salesmen
where territoryID = @v_counter

insert into @v_salestable(territoryID,salesmen) values (@v_counter, right(@v_saleslist,len(@v_saleslist)-1))

set @v_counter = @v_counter + 1

END

select * from @v_salestable
 
Either way is fine. I prefer to filter the NULLs instead. Why bother coalescing when you don't have to.

Anyway... I'm glad you got it to work.


-George

"The great things about standards is that there are so many to choose from." - Fortune Cookie Wisdom
 
Just a comment that you can also use the isnull function so
Code:
case when c.TerritoryID is null then 0 else c.TerritoryID end
would be
Code:
isnull(c.TerritoryID, 0)

Not that your way is wrong just an FYI

djj
The Lord is My Shepard (Psalm 23) - I need someone to lead me!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top