2011-04-05 112 views
2

讓我們說我有兩個表,「花園」和「花」。這些表格之間有1:n的關係,因爲在花園裏可以有很多花。是否可以編寫一個SQL查詢返回的結果結構如下:SQL查詢問題

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

RDBMS是什麼?一般來說,這隻有在您定義了固定數量的花柱時纔有可能。大多數RDBMS也對列數有限制。 – 2011-04-05 15:32:59

+0

MS SQL-Server2008 ... – AGuyCalledGerald 2011-04-05 15:34:37

+0

Frederik - 你可以顯示你的表結構嗎? – JNK 2011-04-05 15:50:46

回答

8
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 

返回

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

我不假裝明白這一點,但我測試了它,它似乎工作。對於每個花園,它總是填充左側的列,並將空值留在右側。 Joe Enos對它的描述並不漂亮,但功能上+1! – Fillet 2011-04-05 16:26:01

+0

是的,這是一個嚴重的問題。我對你來說@Fillet,我真的不知道那裏發生了什麼,但它正在做一些很酷的事情。 – 2011-04-05 22:45:29

2

動態SQL與遊標是我能想到的唯一途徑,而且也不會漂亮。

6

看看在SQL Server中使用Pivot。這裏是一個很好的鏈接,越過它是如何工作:

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

好吧,我想我得到它的工作。試試這個:

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 

你也可以將在in條款的動態值。由於這是一個CTE,我不能在我的例子中。

+0

+1 Oracle也有一個支點條款。 – Jonathan 2011-04-05 15:36:06

+0

儘管如此,這並不會做OP所需要的。你需要一些屬性來轉動。 – 2011-04-05 15:38:12

+0

看起來很有趣... – AGuyCalledGerald 2011-04-05 15:41:00

0

如果你只是想在這個時間會給你的數據,一個花園結果:

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