SUB-ÁRVORE DENTRO DE UMA ÁRVORE no MySQL
No meu MYSQL Database COMPANY
, eu tenho uma Table: Employee
associação recursiva, um funcionário pode ser chefe de outro funcionário. A self relationship of kind (SuperVisor (1)- SuperVisee (∞) )
.
Consulta para criar tabela:
CREATE TABLE IF NOT EXISTS `Employee` (
`SSN` varchar(64) NOT NULL,
`Name` varchar(64) DEFAULT NULL,
`Designation` varchar(128) NOT NULL,
`MSSN` varchar(64) NOT NULL,
PRIMARY KEY (`SSN`),
CONSTRAINT `FK_Manager_Employee`
FOREIGN KEY (`MSSN`) REFERENCES Employee(SSN)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Eu inseri um conjunto de tuplas (consulta):
INSERT INTO Employee VALUES
("1", "A", "OWNER", "1"),
("2", "B", "BOSS", "1"), # Employees under OWNER
("3", "F", "BOSS", "1"),
("4", "C", "BOSS", "2"), # Employees under B
("5", "H", "BOSS", "2"),
("6", "L", "WORKER", "2"),
("7", "I", "BOSS", "2"),
# Remaining Leaf nodes
("8", "K", "WORKER", "3"), # Employee under F
("9", "J", "WORKER", "7"), # Employee under I
("10","G", "WORKER", "5"), # Employee under H
("11","D", "WORKER", "4"), # Employee under C
("12","E", "WORKER", "4")
As linhas inseridas têm o seguinte relacionamento hierárquico em árvore :
A <---ROOT-OWNER
/|\
/ A \
B F
//| \ \
// | \ K
/ | | \
I L H C
/ | / \
J G D E
Eu escrevi uma consulta para encontrar relacionamento:
SELECT SUPERVISOR.name AS SuperVisor,
GROUP_CONCAT(SUPERVISEE.name ORDER BY SUPERVISEE.name ) AS SuperVisee,
COUNT(*)
FROM Employee AS SUPERVISOR
INNER JOIN Employee SUPERVISEE ON SUPERVISOR.SSN = SUPERVISEE.MSSN
GROUP BY SuperVisor;
E a saída é:
+------------+------------+----------+
| SuperVisor | SuperVisee | COUNT(*) |
+------------+------------+----------+
| A | A,B,F | 3 |
| B | C,H,I,L | 4 |
| C | D,E | 2 |
| F | K | 1 |
| H | G | 1 |
| I | J | 1 |
+------------+------------+----------+
6 rows in set (0.00 sec)
[ PERGUNTA ]
Em vez da árvore hierárquica completa, preciso SUB-TREE
de um ponto (seletivo), por exemplo:
se o argumento de entrada for, B
então a saída deve ser a seguinte ...
+------------+------------+----------+
| SuperVisor | SuperVisee | COUNT(*) |
+------------+------------+----------+
| B | C,H,I,L | 4 |
| C | D,E | 2 |
| H | G | 1 |
| I | J | 1 |
+------------+------------+----------+
Por favor me ajude nisso. Caso contrário, um procedimento armazenado pode ser útil.
Eu tentei, mas todos os esforços foram inúteis!
mysql
stored-procedures
Grijesh Chauhan
fonte
fonte
It my experience
Sempre obtive uma resposta melhor de especialistas . E acho que foi melhor decisão passar a pergunta para os administradores de banco de dados. Em todos os casos, sou muito grato ao stackoverflow e às pessoas que estão ativas aqui. Eu realmente tenho solução para muitos problemas que eram muito difíceis de encontrar ou para qualquer outra web.Respostas:
Eu já resolvi algo dessa natureza usando Procedimentos armazenados: encontre o nível mais alto de um campo hierárquico: com vs sem CTEs (24 de outubro de 2011)
Se você olhar no meu post, poderá usar as funções GetAncestry e GetFamilyTree como modelo para percorrer a árvore a partir de qualquer ponto.
UPDATE 2012-12-11 12:11 EDT
Olhei para o meu código da minha postagem . Eu escrevi a Função Armazenada para você:
Isso realmente funciona. Aqui está uma amostra:
Há apenas uma captura. Adicionei uma linha extra para o proprietário
Aqui estão os dados
fonte
A
como estaA A/B A/B/C A/B/C/D A/B/C/E A/B/H A/B/H/G A/B/I A/B/I/J A/B/L A/F A/F/K
O que você está usando é chamado Modelo de Lista de Adjacência . Tem muitas limitações. Você será um problema quando desejar excluir / inserir um nó em um local específico. É melhor você usar o modelo de conjunto aninhado .
Há uma explicação detalhada . Infelizmente, o artigo no mysql.com não existe mais.
fonte