April 1, 2008 at 5:58 am
Say I have a Product table with ProductID and ProductDescription.
And I have a Colour table with ColourID and Colour Description and a ProductColour table.
So, Product table might have:
ProductID ProductDescription
2427 10cm x 20cm plastic box
The Colour table might have:
ColourID Colour Description
1 Red
2 Blue
3 Green
4 Yellow
5 Purple
The ProductColour table might have
ProductID ColourID
2427 1
2427 2
2427 4
Which means ProductID 2427 is available in Red, Blue and Yellow
If I run a query like ...
SELECT ProductID, ProductDescription, Colour
FROM Product INNER JOIN
ProductColour ON Product.ProductID = ProductColour.ProductID INNER JOIN
Colour ON ProductColour.ColourID = Colour.ColourID
I will get data like:
2427 10cm x 20cm plastic box Red
2427 10cm x 20cm plastic box Blue
2427 10cm x 20cm plastic box Yellow
But, what I want to get back is just one row like this ...
2427 10cm x 20cm plastic box Red, Blue, Yellow
How can you concatenate the data from the many side of a relationship so it can be returned in one row?
Thanks for any help.
April 1, 2008 at 6:07 am
SELECT p.ProductID,
p.ProductDescription,
STUFF((SELECT ','+c.Colour AS "data()"
FROM Colour c
INNER JOIN ProductColour pc ON pc.ColourID=c.ColourID
AND pc.ProductID=p.ProductID
ORDER BY c.ColourID
FOR XML PATH('')),1,1,'') AS Colours
FROM Product p
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537April 1, 2008 at 8:32 am
Hi, thanks for your reply.
I get a syntax error though ...
Incorrect syntax near the keyword 'FOR'.
... but can't work out what I am doing wrong.
Cheers.
April 1, 2008 at 8:35 am
Are you running SQL Server 2005?
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537April 1, 2008 at 8:50 am
I believe that's a 2005 only construct. If you are running 2000, you posted in the wrong place. Let us know and we'll help.
In 2000, there's no good way to do this. If you know how many (max) colors there are, you can write multiple joins to handle this. Or you can loop through. This is really a client thing and you'd be better off handling this on the client side.
April 2, 2008 at 12:03 pm
The way I've handled this in 2000 (and 2005) is to use a User Defined Function to string the text together. You have to be careful about using this technique since it is hidden RBAR (Row By Agonizing Row). It has to run basically a sub-query for each row evaluated in order to string each product's color.
Here's the query:
SELECT
ProductID
, ProductDescription
, dbo.fnStringColors(ProductID) AS Colors
FROM
Product
Here's the function to call:
CREATE FUNCTION fnStringColors
(
@ProductID INT
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE
@Color VARCHAR(MAX)
, @Comma VARCHAR(1)
SET @Color = ''
SET @Comma = ''
SELECT @Color = @Comma + @Color + X.Color, @Comma = ','
FROM
(SELECT PC.Color
FROM ProductColour PC
INNER JOIN Color C ON
PC.ColourID = C.ColourID
WHERE PC.ProductID = @ProductID
) AS X
RETURN @Color
END
April 2, 2008 at 12:06 pm
Actually, I made a typo in the above function. It should read SELECT C.Colour. PC is the alias for ProductColour, not the Colour table.
Todd Fifield
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply