AGuyCalledGerald
AGuyCalledGerald

Reputation: 8150

SQL query problem

Let´s say I have two tables, "Garden" and "Flowers". There is a 1:n-relationship between these tables, because in a garden can be many flowers. Is it possible to write an SQL query which returns a result with the following structure:

GardenName     Flower1Name      Flower2Name .... (as long as there are entries in flowers)
myGarden        rose             tulip

Upvotes: 2

Views: 579

Answers (4)

Patrick
Patrick

Reputation: 8300

If you only want the results for one garden at a time this would give you the data:

select gardenName from tblGarden where gardenid = 1 
Union ALL 
select tblFLowers.flowerName from tblFlowers where gardenid = 1

Upvotes: 0

Abe Miessler
Abe Miessler

Reputation: 85036

Look at using Pivot in SQL Server. Here is a good link that goes over how it works:

http://www.kodyaz.com/articles/t-sql-pivot-tables-in-sql-server-tutorial-with-examples.aspx

Ok, i think i got it working. Try this:

with temp as
(
    select 'myGarden' as name, 'test1' as flower
    union
    select 'myGarden','test2'
    union
    select 'myGarden','test5'
    union
    select 'abeGarden','test4'
    union
    select 'abeGarden','test5'
    union 
    select 'martinGarden', 'test2'
)

select* from temp
pivot
(
  max(flower)
  for flower in (test1,test2,test3,test4,test5)
) PivotTable

You could also make the values in the in clause dynamic. Since this is a CTE i can't in my example.

Upvotes: 6

Martin Smith
Martin Smith

Reputation: 452977

CREATE TABLE #Garden (Id INT, Name VARCHAR(20))
INSERT INTO #Garden
SELECT 1, 'myGarden' UNION ALL
SELECT 2, 'yourGarden'

CREATE TABLE #Flowers (GardenId INT, Flower VARCHAR(20))
INSERT INTO #Flowers
SELECT  1, 'rose'  UNION ALL
SELECT  1, 'tulip'  UNION ALL
SELECT  2, 'thistle' 

DECLARE @ColList nvarchar(max)

SELECT @ColList = ISNULL(@ColList + ',','') + QUOTENAME('Flower' + CAST(ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS VARCHAR))
FROM #Flowers WHERE GardenId = (
SELECT TOP 1 GardenId
FROM #Flowers
ORDER BY COUNT(*) OVER (PARTITION BY GardenId) DESC

)

EXEC (N'
;WITH cte As
(
SELECT *, ''Flower'' + CAST(ROW_NUMBER() OVER (PARTITION BY GardenId ORDER BY (SELECT 0)) AS VARCHAR) RN
FROM #Flowers F
)
SELECT Name,' + @ColList + N'
FROM cte 
JOIN #Garden g ON g.Id = GardenId
PIVOT (MAX(Flower) FOR RN IN (' + @ColList + N')) Pvt')


DROP TABLE #Garden
DROP TABLE #Flowers

Returns

Name                 Flower1              Flower2
-------------------- -------------------- --------------------
myGarden             rose                 tulip
yourGarden           thistle              NULL

Upvotes: 8

Joe Enos
Joe Enos

Reputation: 40383

Dynamic SQL with a cursor is the only way I can think of, and it won't be pretty.

Upvotes: 2

Related Questions