complexas linhas de árvore de sql
-
12-09-2019 - |
Pergunta
estrutura de tabela
id | message | reply_id
1 | help me! | 0
434 | love to | 1
852 | didn't work | 434
0110 | try this | 852
2200 | this wont | 0
5465 | done. :) | 0110
eu tenho um id "852", que é meio do menu da árvore, mas eu quero pegar todas as linhas relacionadas anteriores relacionadas e próximas, então eu quero começar a seguir os resultados como este:
help me! > Amor> não funcionou> tentar isso> feito. :) (Este resultado mostra como que depois de loop PHP, mas começa looping de ID de arranque 1 com ID de resposta 0.
NOTA:. 2200 ID não mostrou no resultado, porque não é parte do grupo
Solução
Existem várias alternativas para tornar a informação hierárquica mais fácil trabalhar com em SQL:
-
Expressions Common Table (por padrão SQL-2003) suportam consultas SQL recursiva contra o tipo pai-id de dados que você está usando. Até agora, o MySQL não suporta este recurso. PostgreSQL 8.4, Microsoft SQL Server, e IBM DB2 são exemplos de RDBMS marcas que o apoio sintaxe CTE. A Oracle também tem uma extensão de propriedade da sintaxe SQL que suporta consultas recursivas.
-
conjuntos aninhados (a solução esquerda / direita que @phantombrain menciona) é uma solução detalhada no livro "Árvores e hierarquias em SQL para Smarties" Joe Celko e também em numerosos artigos e blogue postagens na internet.
-
Caminho enumeração (aka materializou Path) lojas de uma string em cada linha na hierarquia notar o caminho dos antepassados ??desta linha. Combine isso com consultas
LIKE
comparar a cadeia de caminho para caminhos e descendentes de seus antepassados ??caminhos. -
Encerramento Tabela (aka Transitivo Encerramento Relação) usa uma segunda tabela para armazenar todas as relações ancestral-descendente, e não apenas o pai imediato como no desenho que você está usando. Muitos tipos de consultas se tornam mais fáceis quando você tem todos os caminhos armazenados.
-
soluções híbridas também existem. Por exemplo, armazenar o id pai imediato como você está fazendo, mas também a raiz da árvore. Agora você pode obter todas as outras linhas da mesma hierarquia, buscá-los no código do aplicativo, e resolver a árvore com estruturas de dados convencionais.
Outras dicas
Assumindo que estes são itens de menu e não algo muito dinâmico, como um fórum, eu recomendaria uma alteração de esquema para adicionar valores de esquerda e direita para cada item. Os IDs entre os valores de esquerda e direita são todos filhos do nó que você está consultando. Assim, é fácil de fazer uma consulta para obter a esquerda / valores corretos, e uma segunda consulta para obter os sub-itens.
http://www.sitepoint.com/print/hierarchical-data -database / para mais informações
A recursão é a maneira mais elegante de fazer isso, mas eu não acho que o MySQL suporta-lo em funções personalizadas ou StoredProcedures. Gostaria de sugerir um loop em uma tabela temporária ou variável de tabela para obter seus IDs, em seguida, juntar-se à mesa e consultar os resultados de volta. Eu não sei mySql muito bem assim que este não foi testado, mas algo nesse sentido.
CREATE TEMPORARY TABLE tbl (myid int, ViewOrder int);
Set @ifoundID=IdYourLookingFor;
Set @iStartID=@ifoundID;
Set @iOrder=0;
INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);
BEGIN --get the ones going up
WHILE (@ifoundID Is Not Null) DO
SELECT @ifoundID=reply_id FROM YourTable WHERE id=@ifoundID; --find the next id
SET @iOrder1=@iOrder-1; --increment the order
INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
END WHILE;
END
Set @ifoundID=@iStartID;
BEGIN --get the ones going down
WHILE (@ifoundID Is Not Null) DO
SELECT @ifoundID=id FROM YourTable WHERE reply_id=@ifoundID; --find the next id
SET @iOrder1=@iOrder+1; --increment the order
INSERT INTO tbl(myid,ViewOrder)VALUES(@ifoundID,@iOrder);--save the nextid
END WHILE;
END
SELECT * FROM tbl INNER JOIN YourTable ON tbl.myid=YourTable.id ORDER BY ViewOrder
Espero que ajude