Таблицы закрытия MySQL: как получить данные в правильном порядке, если для ребенка существует несколько родителей?
Я использую таблицы закрытия аналогично этому ответу. У меня есть следующие две таблицы:
CREATE TABLE `part` (
`id` int(11) NOT NULL,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Какая таблица содержит данные.
CREATE TABLE `BOM` (
`ancestor_id` int(11) NOT NULL,
`descendant_id` int(11) NOT NULL,
`quantity` int(11) DEFAULT NULL,
`length` int(11) DEFAULT NULL,
PRIMARY KEY (`ancestor_id`,`descendant_id`),
KEY `fk_BOM_part1_idx` (`ancestor_id`),
KEY `fk_BOM_part2_idx` (`descendant_id`),
CONSTRAINT `fk_BOM_part1` FOREIGN KEY (`ancestor_id`) REFERENCES `part` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_BOM_part2` FOREIGN KEY (`descendant_id`) REFERENCES `part` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Какой стол закрытия. Он использует длину столбца, чтобы записать, насколько глубоко вы находитесь в дереве. Это тестовые данные, которые я использую:
INSERT INTO `BOM` (`ancestor_id`, `descendant_id`, `quantity`, `length`) VALUES (1,1,3,0),(3,1,3,1),(3,3,1,0),(4,1,7,1),(4,4,1,0);
INSERT INTO `part` (`id`, `name`, `part_type_id`) VALUES (1,'A',1),(2,'B',1),(3,'1',1),(4,'2',1);
В случае, когда у каждого потомка ровно один родитель, следующий запрос выводит все дерево в правильном порядке:
select
part.id AS id,
concat(repeat('-', MAX(tree.length)), part.name) as name,
group_concat(distinct tree.quantity) as quantity,
group_concat(tree.ancestor_id order by tree.length desc separator ',') as breadcrumbs
from part
join BOM tree on
part.id = tree.descendant_id
group by part.id
order by breadcrumbs;
Однако это не работает, если в базе данных есть несколько родителей для одного и того же ребенка. Что я получаю это:
1
2
-A
Что я хочу это:
1
-A
2
-A
Я понимаю, почему это происходит, но я не знаю, как это исправить. Какой запрос я должен использовать, чтобы вытащить все дерево в правильном порядке?