0

I am using closure tables in a similar way to this answer. I have the following two tables:

CREATE TABLE `part` (
  `id` int(11) NOT NULL,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Which is the table holding the data.

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;

Which is the closure table. It uses a column length in order to record how deep you are in the tree. This is the test data I am using:

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);

In the case when each child has exactly one parent the following query outputs the entire tree in the correct order:

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;

However this does not work when there are multiple parents for the same child in the database. What I get is:

1
2
-A

What I want is:

1
-A
2
-A

I understand why this happens, but I do not know how to fix it. What query should I use to pull the entire tree in the correct order?

Community
  • 1
  • 1
user110971
  • 153
  • 7

0 Answers0