2016-12-30 10 views
2

Id、ParentId、名前、説明などのプロパティを持つテーブルServiceItemがあります。テーブルから階層を選択

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' 

    ) 

しかし、階層の最大レベルは、私のようななめらかを取得する例Name = '123'ためのいくつかの条件で行を選択する問合せ、およびその親行を必要とする2ですそれは親を返し、そのすべては子です。 1つのクエリでそれを行う機会はありますか?私はそれを行うためにT-SQLを使用しています。

これはthis questionとは異なります。パスのIDだけでなく、クエリの条件が異なる可能性があるため、たくさんの行を取得する必要があるためです。

+0

[IDとparentIdを持つテーブル内のパスをトラバースする方法](http://stackoverflow.com/question) s/37197500/how-to-traverse-a-path-in-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 

を参照してくださいそれは良いのクエリですが、私はまた、この1が見つかりました:

SELECT 
    * 
FROM ServiceItem si 
WHERE si.Name = '123' 
    OR EXISTS (
     SELECT 
      * 
     FROM ServiceItem si2 
     WHERE si2.Name = '123' 
      and si2.ParentId = si.Id 
    ) 
関連する問題