質問

エリアテーブル(id、parentId、name、path)があるとしましょう。

IDが与えられたら、指定されたエリアのすべての子供(再帰的に含まれる子供の子供)を取得したいです。

親から子へのパスをパスに保存します。

例:

1 NULL New York /1/
2 1    BRONX    /1/2/
3 1    MANH     /1/3/ 
4 3    UpWest   /1/3/4/
5 3    MidEast  /1/3/5/

したがって、ニューヨークの子供たちを尋ねるとき、クエリはbronx、manh、upwest、mideastを返す必要があります。ブロンクスとマンだけではありません。

役に立ちましたか?

解決

idが1の都市(たとえば、ニューヨーク)の子であるすべてのエリアを返します。その番号を他の都市に変更して、その子も返すことができます

select * from areas where path like '%/1/%'

他のヒント

使用できます

SELECT * FROM Areas WHERE Path LIKE '%/1/%'

パスが保存されている場合

設定した数値の深さがわかっている場合、これはあなたが望むことをするよりも深くなることはありません:

select * from areas a1
join areas a2 on a1.id = a2.parent
join areas a3 on a2.id = a3.parent
join areas a4 on a3.id = a4.parent
join areas a5 on a4.id = a5.parent
where a1 = 1; --or whatever value you're searching for.

編集: ただし、既にパスを保存している場合(これまで気づかなかった)、 '%/ 1 /%'などのパスが明らかに優れたソリューションです。

MySQL 内:

SELECT  *
FROM    Areas ap
JOIN    Areas ac
ON      ac.path > ap.path
        AND ac.path < CONCAT(ap.path, ':')
WHERE   ap.id = 1

PostgreSQL および Oracle の場合:

SELECT  *
FROM    Areas ap
JOIN    Areas ac
ON      ac.path > ap.path
        AND ac.path < ap.path || ':'
WHERE   ap.id = 1

SQL Server 内:

SELECT  *
FROM    Areas ap
JOIN    Areas ac
ON      ac.path > ap.path
        AND ac.path < ap.path + ':'
WHERE   ap.id = 1

LIKE (しゃれなし)とは異なり、これは path のインデックスを使用します。

Oracle SQLでSTART WITHおよびCONNECT BYを探します。 このようにして、階層関係(ツリーのような)を持つデータを選択できます。

これを試してください:

declare @id int
select @id = 1;

with CustParent (ParentID,ChildID)
            as
            (
                select o.ParentID, o.ChildID
                from Customer o
                where o.ID = @id
                union all
                select cpc.ParentID ,cpc.ID 
                from Customer cpc 
                inner join CustParent cp on cp.ChildID = cpc.ParentID
            )   

Select Customer.ChildID, Customer.ParentID
from Customer 
inner join CustParent cp on cp.ChildID = Customer.ChildID

私はこれを常に再利用しています。

使用しているデータベースがわからない:SQL Serverの場合、共通テーブル式を使用する( CTE

それ以外の場合、

何らかのコードまたはストアドプロシージャが必要です。psuedoCodeの使用

   Assuming @Parent is Primary key of Area record you want children of...
   --Create Temp table (Does your DB have temp Tables) of Keys 
   --  Say it's called 'Children'
   -- -- make this a temmp table... 
   --  In SQL Server syntax uses a #.
   --  Create Table #Table...  ( or use table variable Declare @Children Table ... ), 
   --  Oracle, MySql have their own syntax... 


   Create Table Children 
   (PK Integer Primary Key Not Null)
   -- -------------------------
   Insert Children(PK)
   Select PK From Area 
   Where Parent = @Parent
   -- -----------------------
   While Exists (Select * From 'Children' As C
                 Where Exists 
                    (Select * From Area
                     Where parent = C.PK
                       And PK Not In
                          (Select PK From 'Children')))
       Begin
           Insert Children(PK)
           Select PK From Area
           Where Parent In (Select PK From Children)
              And PK Not In (Select PK From Children)
       End

   --Then join temp table to Area table and return results

   Select a.* From Area a 
      Join Children C On C.PK = A.PK

SQLite:

SELECT * FROMパスのような領域 (SELECTパス|| '%' FROMエリアWHERE area =&quot;ニューヨーク&quot;)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top