2016-12-30 71 views
2

我有一個表的ServiceItem具有Id,ParentId和一些屬性,如Name,Description等。層次結構的最大級別爲2。我需要查詢一些條件選擇行,例如Name = '123'和其父行即可水木清華這樣的:從表中選擇層次結構

Id ParentId Name 
1 NULL  '12' 
2 1   '123' 

我已經試過這樣:

SELECT 
    * 
FROM ServiceItem si 
WHERE si.Name = '123' 
    OR EXISTS (
     SELECT 
      * 
     FROM ServiceItem syst 
      JOIN ServiceItem si2 
       ON si2.ParentId = syst.Id 
     WHERE syst.Id = si.ParentId 
      AND si2.Name = '123' 

    ) 

但它會返回父項及其全部子項。有沒有機會用一個查詢來做到這一點?我正在使用T-SQL來做到這一點。

它不同於this question,因爲我需要一堆行,不僅我的查詢中的路徑和條件可能會有所不同。

+0

可能的重複[如何遍歷表中的id與parentId?](http://stackoverflow.com/question s/37197500/how-to-traverse-a-path-in-a-table-with-id-parentid) –

+0

@a_horse_with_no_name不,這不是我要找的。 –

+0

[Sql server CTE和遞歸示例]的可能重複(http://stackoverflow.com/questions/14274942/sql-server-cte-and-recursion-example)。您必須修改查詢以使用樹的底部而不是頂部來啓動樹,但它本質上是相同的語法。 –

回答

1

您可以使用公用表表達式遞歸:

WITH cte AS 
    (
    SELECT  * 
    FROM  ServiceItem 
    WHERE  Name = '123' 
    UNION ALL 
    SELECT  * 
    FROM  ServiceItem si 
    INNER JOIN cte 
      ON cte.ParentId = si.Id 
) 
SELECT * FROM cte 

爲了更深入的例子,看到this Q&A

+0

@trinkot是的,我工作就像我需要它。謝謝。 –

0
WITH cte AS 
    (
    SELECT  * 
    FROM  ServiceItem 
    WHERE  Name = '123' 
    UNION ALL 
    SELECT  * 
    FROM  ServiceItem si 
    INNER JOIN cte 
      ON cte.ParentId = si.Id 
) 
SELECT * FROM cte 

這是一個很好的查詢,但我也發現了這一個:

SELECT 
    * 
FROM ServiceItem si 
WHERE si.Name = '123' 
    OR EXISTS (
     SELECT 
      * 
     FROM ServiceItem si2 
     WHERE si2.Name = '123' 
      and si2.ParentId = si.Id 
    )