SQL создает полный список деталей из заданного списка деталей (итерация) - PullRequest
1 голос
/ 20 апреля 2019

У меня проблема с заданием из моей лекции по SQL.В задании есть база данных, содержащая список частей трех роботов и другой список, в котором эти части связаны с частями из первого списка, из которых они сделаны, если они сделаны из других частей.

Базы данных могут быть сгенерированы с помощью:

CREATE TABLE part (
part_id BIGINT PRIMARY KEY,
part_namevarchar(64)NOTNULL
);

CREATE TABLE part_part (
    object_id BIGINT,
    part_id BIGINT,
    quantity INT NOT NULL,
    PRIMARY KEY(object_id, part_id)
);
ALTER TABLE part_part
 ADD CONSTRAINT part_id_fkey FOREIGNKEY (part_id) REFERENCES part(part_id)
 ON UPDATE CASCADE ON DELETE CASCADE;

 ALTER TABLE part_part
 ADD CONSTRAINT object_id_fkey FOREIGN KEY(object_id)REFERENCES part(part_id)
 ON UPDATE CASCADE ONDELETE CASCADE;

 INSERT INTO part(part_id, part_name)
 VALUES
 (0,'CPU A'),
 (1,'Cables'),
 (2,'Motherboard 3xy'),
 (3,'Motor ayX'),
 (4,'Arm'),
 (5,'Body'),
 (6,'Leg'),
 (7,'Wheel'),
 (8,'Motherboard 7ax'),
 (9,'Joint'),
 (10,'Motor Z1238'),
 (11,'Hammer'),
 (12,'Screw A'),
 (13,'Screw B'),
 (14,'Screw C'),
 (15,'Robo 1000'),
 (16,'CPU B'),
 (17,'CPU C'),
 (18,'Robo 2000'),
 (19,'Screwdriver'),
 (20,'Robo 3000');

 INSERT INTO part_part
 (object_id, part_id, quantity)
 VALUES
 (5,2,1),
 (5,0,1),
 (5,3,2),
 (5,1,5),
 (5,12,3),
 (4,9,3),
 (4,10,3),
 (4,13,13),
 (6,3,2),
 (6,7,4),
 (15,4,2),
 (15,11,2),
 (15,5,1),
 (15,6,1),
 (18,4,2),
 (18,11,2),
 (18,5,1),
 (18,6,2),
 (18,16,1),
 (20,4,3),
 (20,11,1),
 (20,19,1),
 (20,5,1),
 (20,6,1),
 (20,16,1),
 (20,17,1);

Теперь задача состоит в том, чтобы получить список всех деталей и узлов, необходимых для "Robo 3000", и их количество.

Я получилнасколько:

WITH part2(part_name1, subpart_id, top_quantity, top_part_id, part_name) AS(
  WITH part1(part_name, subpart_id, quantity) AS(
  WITH subpart1(object_id, subpart_id, quantity) AS(SELECT * FROM part_part)
  SELECT part_name, subpart_id, quantity FROM subpart1
    JOIN part ON part.part_id = subpart1.object_id
     WHERE part_name = 'Robo 3000'
  )
  SELECT * FROM part1
  JOIN part ON part1.subpart_id = part.part_id
)
SELECT * FROM part2
JOIN part_part ON part2.top_part_id = part_part.object_id
ORDER BY top_part_id;

, который дает мне список только частей (частей всех частей от робота, которые нуждаются в самих частях), а также не учитывает, если части используются несколькораз, здесь рука используется 3 раза, но ее части не умножаются на количество.

Также это ограничено, так как она смотрит только на данную часть и части поддержки, но не глубже, если это необходимо.

Есть ли способ перебрать все части и превратить их в большой список в SQL?

Точно так же, как, например, метод java с методом самовызывания?

1 Ответ

1 голос
/ 20 апреля 2019

PostgreSQL поддерживает рекурсивный sQL , который может быть одним из способов решения вашей проблемы.Ниже приведен пример использования ваших данных.

with recursive part_list as
(
    (
    select object_id as unit, object_id, part_id, quantity, quantity as totqty 
      from  part_part 
     where object_id = 20
    )
    union
    select pl.unit, pp.object_id, pp.part_id, pp.quantity, pp.quantity * pl.quantity
      from part_part pp 
      join part_list pl
        on pp.object_id = pl.part_id
)
select u.part_name as unit,
        part.part_name, 
        sum(part_list.totqty) as total_parts
  from part_list
  join part u
    on u.part_id = part_list.unit
  join part 
    on part.part_id = part_list.part_id
group by u.part_name, part.part_name    
order by 1,3;
...