0

Я пытаюсь узнать, как использовать общие выражения таблиц, представленные в SQL 1999 для решения общей проблемы с материалами. Я полагаю, учитывая следующие таблицы:Рекурсивный CTE в SQLite

create table part(id int, name string, price int) 
create table assembly(part_id int, subpart_id int, quantity int) 

Строка в таблице сборки представляет тот факт, что часть содержит несколько примеров подразделу, которые в свою очередь имеют свои собственные подразделы и так далее. Таблица сборки представляет собой структуру, дерево, с заданным part_id в качестве ее корня.

Я хотел бы вычислить общее количество вхождений каждой части в структуре.

Вот моя попытка использования общих табличных выражений:

WITH RECURSIVE bom(part_id, component_id, total) AS 
    (SELECT id, id, 1 FROM part 
     UNION 
    SELECT assembly.part_id, bom.component_id, sum(assembly.quantity * bom.total) 
    FROM assembly, bom 
    WHERE assembly.subpart_id = bom.part_id 
    GROUP BY assembly.part_id, bom.component_id) 
SELECT component_id, total FROM bom WHERE part_id = root; 

Под SQLite 3.9.1 на Mac OS X 10.9.5, я получаю следующее сообщение об ошибке: Ошибка: вблизи линии 78: рекурсивный агрегатные запросы не поддерживается

Итак, это ограничение SQLite, или это стандартное ограничение SQL?

В любом случае, может ли кто-нибудь посоветовать мне, как переписать это решение, чтобы накапливать больше информации в общем выражении таблицы, а затем выполнить агрегат в запросе, который использует результирующую таблицу?

Большое спасибо, Родни

+0

Ваш пример работает для меня с sqlite3. – qoba

+0

Postgres также отказывается это делать. Но я думаю, что ваша сумма() ошибочна в первую очередь. Я думаю, что вы хотите просто bom.total + assembly.quantity (таким образом добавляя все значения количества в дереве). Плюс, я думаю, что было бы более эффективно, если бы вы выбрали корневой узел непосредственно внутри CTE: 'from part id = root' –

+0

Возможно, я недостаточно четко описал проблему. Если в автомобиле есть 4хождения колес в машине, а 5 случаев гайки в колесе, то должно быть 20 случаев гайки в автомобиле. Поэтому вам нужно умножить количество на общее количество. Затем вам нужно суммировать все промежуточные части, например, колеса и другие субчасти, содержащие орехи. –

ответ

0

Вот простой способ решить эту проблему путем перемещения агрегации для внешнего запроса:

WITH RECURSIVE bom(part_id, component_id, total) AS 
    (SELECT id, id, 1 FROM part 
     UNION ALL 
    SELECT assembly.part_id, bom.component_id, assembly.quantity * bom.total 
    FROM assembly, bom 
    WHERE assembly.subpart_id = bom.part_id) 
SELECT component_id, SUM(total) FROM bom 
WHERE part_id = root 
GROUP BY component_id; 

Это решение требует больше места, и, возможно, больше времени, чем первоначальный попытка.

Смежные вопросы