2012-04-16 16 views
6

下面是表的結構例:如何在SQL顯示遞歸的parentID在單個列

ID Name  ParentID 
----------------------- 
1  Ancestor  NULL 
2  GrandFather 1 
3  GrandMother 1 
4  Child   3 

我想編寫一個查詢,將返回

ID  Name  Family 
---------------------------- 
1  Ancestor 
2  GrandFather Ancestor 
3  GrandMother Ancestor 
4  Child  Ancestor^GrandMother 

棘手部分是我想要以自上而下的順序顯示所有行的家族。

如果任何人都可以在正確的方向指向我,我們將不勝感激:)

編輯::這是真正的查詢,但它遵循了同樣的想法。它返回的行錯誤:marketparent.family + '^' + t2.marketGroupName,因爲它無法找到marketparent

WITH marketparent (marketGroupID,parentGroupID, marketGroupName,family) 
AS 
(
SELECT marketGroupID, 
     parentGroupID, 
     marketGroupName, 
     '' as family 
FROM EVE.dbo.invMarketGroups 
WHERE parentGroupID IS NULL 
UNION ALL 

    SELECT t2.parentGroupID, 
    t2.marketGroupID, 
    t2.marketGroupName, 
    marketparent.family + '^'+ t2.marketGroupName 
    FROM EVE.dbo.invMarketGroups as t2 
    INNER JOIN marketparent as mp 
    ON mp.marketGroupID = t2.parentGroupID 
) 

-- Statement using the CTE 

SELECT TOP 10 * 
FROM marketparent; 
+3

該解決方案將取決於您使用的DBMS。 SQL Server,Oracle,MySQL或....? – 2012-04-16 15:02:40

+0

我使用SQL Server 2008 – darthun08 2012-04-16 15:13:11

+0

使用別名'mp'而不是'marketparent'。 – 2012-04-16 16:48:41

回答

5

你沒有指定你的DBMS,所以我假定PostgreSQL的

WITH RECURSIVE fam_tree (id, name, parent, family) as 
(
    SELECT id, 
     name, 
     parentid, 
     ''::text as family 
    FROM the_unknown_table 
    WHERE parent IS NULL 

    UNION ALL 

    SELECT t2.id, 
     t2.name, 
     t2.parentid, 
     fam_tree.family || '^' || t2.name 
    FROM the_unknown_table t2 
    INNER JOIN fam_tree ON fam_tree.id = t2.parentid 
) 
SELECT * 
FROM fam_tree; 

這是標準的SQL(除了::text類型轉換),它們應該能夠在大多數現代DBMS上進行很少的更改。

編輯

對於SQL Server,你就需要更換與微軟的非STANDAR +標準concatention字符(你需要刪除它是由標準,但一些奇怪的原因所需要的recursive關鍵字被SQL Server拒絕)

WITH fam_tree (id, name, parent, family) as 
(
    SELECT id, 
     name, 
     parentid, 
     '' as family 
    FROM the_unknown_table 
    WHERE parent IS NULL 

    UNION ALL 

    SELECT t2.id, 
     t2.name, 
     t2.parentid, 
     fam_tree.family + '^' + t2.name 
    FROM the_unknown_table t2 
    INNER JOIN fam_tree ON fam_tree.id = t2.parentid 
) 
SELECT * 
FROM fam_tree; 
+0

現在,如果我想要生成另一個表中的行的家族,但該表中有一個外鍵,我可以在最後一個查詢中添加一些代碼,還是必須將某些內容放在WITH中? – darthun08 2012-04-16 15:31:53

+0

fam_tree.family +'^'+ t2.name返回錯誤:無法綁定多部分標識符「fam_tree.family」。這可能是由於我沒有在我的問題中指定正確的語言。我正在使用MS SQL Server 2008,至於其他的,我不知道你需要什麼信息:P – darthun08 2012-04-16 15:44:54

+0

@ user1336586:hmm,'fam_tree.family +'^'+ t2.name'應該適用於所有人我知道。由於我沒有桌子,我會假設一些錯字。嘗試在與部分移除列定義:'與fam_tree爲(...'' – 2012-04-16 16:15:45

0

您可以使用遞歸Common Table Expression

declare @T table 
(
    ID int, 
    Name nvarchar(15), 
    ParentID int 
); 

insert into @T values 
(1,  N'Ancestor',  NULL), 
(2,  N'GrandFather', 1), 
(3,  N'GrandMother', 1), 
(4,  N'Child',   3); 

with C as 
(
    select T.ID, 
     T.Name, 
     T.ParentID, 
     cast(N' ' as nvarchar(max)) as Family 
    from @T as T 
    where T.ParentID is null 
    union all 
    select T.ID, 
     T.Name, 
     T.ParentID, 
     C.Family+'^'+C.Name 
    from @T as T 
    inner join C 
     on T.ParentID = C.ID 
) 
select C.ID, 
     C.Name, 
     stuff(C.Family, 1, 2, '') as Family 
from C; 
+0

非常感謝,我會盡力 – darthun08 2012-04-16 15:16:38

+0

@user爲你解決這個問題嗎?我看到你在接受答案時遇到了一些問題,我相信在我的答案中已經考慮到了答案。 – 2012-04-16 19:59:44

+0

不,它沒有工作。我發現了另一個解決方案,我創建一個新表並以迭代方式更新值。如果你有時間,請搜索我的新帖子,我仍然需要同樣的幫助。 – darthun08 2012-04-20 13:32:15

0
select T.ID, T.Name, (select name from table where ID=T.ParentID)as Family 
from table T 
+0

您的查詢似乎只返回每一行的父名稱。這是一個不錯的嘗試,但我正在尋找完整的路徑:) – darthun08 2012-04-16 16:01:19