Сложные агрегатные функции и иерархические структуры в SQL

Я хочу сохранить древовидную структуру произвольной глубины в базе данных SQL (MySQL, но хочу избежать особенностей, специфичных для СУБД). Теперь я хочу вычислить значение N для каждого узла следующим образом:

  • сначала вычислите сумму определенного столбца во всех (непосредственных) дочерних элементах текущего узла, которые являются листьями (т.е. не имеют дочерних элементов)
  • затем вычислите максимум значений N каждого из оставшихся дочерних элементов, т. е. тех, у которых есть дочерние элементы
  • наконец, добавьте результаты первых двух шагов, чтобы получить значение N для текущего узла.

Очевидно, что это включает рекурсию, поэтому вложенные наборы кажутся предпочтительным представлением для этого сценария. Однако я не мог понять, как сформулировать приведенный выше расчет в виде SQL-запроса. Легко получить SUM() или MAX() всех потомков, но способ объединения агрегатных функций сильно усложняет задачу. у кого-нибудь есть решение?


person Marc Schütz    schedule 12.09.2010    source источник
comment
Это болезненный расчет. Можете ли вы позволить себе хранить значение N в узлах? Кроме того, должен ли каждый узел появляться один раз в иерархии в целом или узел может появляться в нескольких местах? (Подумайте о разнице между организационной схемой и спецификацией материалов для создания какой-либо сборки.)   -  person Jonathan Leffler    schedule 12.09.2010
comment
Хотели бы вы перейти на другую базу данных, которая поддерживает рекурсивные запросы? Если вы не хотите рассматривать возможность использования другой базы данных, то почему у вас есть требование избегать использования специфических функций MySQL?   -  person Mark Byers    schedule 12.09.2010
comment
@Jonathan Leffler: каждый узел может появиться только один раз, и узлы, не являющиеся выходными, в любом случае содержат пустой столбец (где узлы выхода хранят свое значение). Однако AFAICS потребовал бы предварительного расчета значений во время вставки/обновления, что сделало бы все упражнение недействительным...   -  person Marc Schütz    schedule 13.09.2010
comment
@Mark Byers: этот вопрос возник в основном из академического интереса; на практике все мои деревья имеют тенденцию быть неглубокими и содержать лишь несколько узлов, поэтому я, вероятно, просто вытащу их все и выполню вычисления на стороне клиента.   -  person Marc Schütz    schedule 13.09.2010


Ответы (1)


Что, если бы в схеме также были дополнительные вычисляемые столбцы, такие как глубина и «является конечным узлом»?

Это потребует большего обслуживания (не то чтобы вложенные наборы не требуют обслуживания), но я думаю, что это делает вышеуказанный запрос доступным с использованием «стандартного» SQL.

person Community    schedule 12.09.2010
comment
Это было бы нормально, но, вероятно, не нужно, так как во время запроса можно вычислить и глубину, и конечный узел. - person Marc Schütz; 13.09.2010