Pergunta

Vamos dizer que eu tenho um Áreas de Tabela (id, parentId, nome, caminho).

Dada uma Id, eu gostaria de obter todas crianças (filhos de crianças incluídas, de forma recursiva) da área dada.

Eu faço loja no caminho o caminho dos pais para a criança.

Exemplo:

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/

Assim, quando pedir o que são os filhos de Nova York, a consulta deve retornar Bronx, manh, upwest e médio oriente. e não só Bronx e manh.

Foi útil?

Solução

retornará todas as áreas que são uma criança da cidade com id de 1 (por exemplo, New York). Você pode alterar esse número para qualquer outra cidade para devolvê-lo para crianças demasiado

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

Outras dicas

Você pode usar

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

Se você tem o caminho armazenado

Se você tem uma profundidade número definido que você sabe que nunca vai ir mais fundo do que isso vai fazer o que quiser:

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.

Edit: No entanto, se você já tiver o caminho salvo (que eu não notei até agora), o caminho like '% / 1 /%' é claramente a melhor solução.

Em MySQL:

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

Em PostgreSQL e Oracle:

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

Em SQL Server:

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

LIKE Ao contrário (sem trocadilhos), esta vai usar um índice em path.

Procure começar e CONNECT BY no Oracle SQL. Desta forma, você pode selecionar dados com relações hierárquicas (árvore-like).

Tente isto:

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

Eu reutilizar este o tempo todo.

Não sei o que banco de dados que você está usando: Se o SQL Server, use uma expressão de tabela comum ( CTE )

Caso contrário,

Você precisa de algum tipo de código ou procedimento armazenado .. Usando 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 Areas where path like (SELECT path || '%' FROM Areas WHERE area="New York")

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top