Привет всем!
Есть обычная задачка, подсчет значений всех элементов дерева БД.
Т.е. в БД создана таблица вида:
ключ/главный ключ/сумма/
значение "сумма" присутствует только у ключей нижнего уровня, т.е которые не является для других глывными.
Надо проссумировать все суммы на всех ключах, думал что получится обычной рекурсией, но дык все голову ломаю не выходит...
Здравствуйте, LexerCIT, Вы писали:
LCI>Привет всем! LCI>Есть обычная задачка, подсчет значений всех элементов дерева БД. LCI>Т.е. в БД создана таблица вида:
LCI>ключ/главный ключ/сумма/
LCI>значение "сумма" присутствует только у ключей нижнего уровня, т.е которые не является для других глывными. LCI>Надо проссумировать все суммы на всех ключах, думал что получится обычной рекурсией, но дык все голову ломаю не выходит...
Не совсем понятно. Если действительно надо посчитать все суммы, то вопрос:
Что хранится в поле сумма, если ключ не является кючом нижнего уровня?
Если null, то проблем вообще никаких, если что-то неопределенное, то сначала можно получить все ключи, не являющиеся ключами нижнего уровня. А потом сумма по ключам, не принадлежащим этому множеству.
Или надо посчитать сумму в некотором поддереве с заданным корнем?
Здравствуйте, LexerCIT, Вы писали:
LCI>надо выводить все суммы, а не какую-то одну, т.е. нужна рекурсивная процедура LCI>в глав.ключах в поле суммы хранится null
Если долго не думать, приходит в голову такая последовательность действий.
1. На каждом шаге находим такие ключи, что поле сумма содержит null и все дочерние ключи содержат в поле сумма не null.
2. Записываем в поле сумма этих ключей сумму непосредственный дочерних.
И т.д.
Здравствуйте, LexerCIT, Вы писали:
LCI>надо выводить все суммы, а не какую-то одну, т.е. нужна рекурсивная процедура LCI>в глав.ключах в поле суммы хранится null
Если предположить, что ключ корня дерева = "root", то с можно воспользоваться следующим псевдокодом:
void getChilds(string key, vector<string>& childs)
{
SELECT ключ FROM Дерево WHERE главный_ключ = key
// записываем полученные ключи в контейнер childs
}
int Sum(string key, map<string, int>& m)
{
vector<string> childs;
getChilds(key, childs)
if (childs.size() == 0)
{
// детей нет
m[key] = (SELECT сумма FROM Дерево WHERE ключ = key);
return m[key];
}
else
{
m[key] = 0;
for (vector<string>::iterator it = childs.begin(); it != childs.end(); ++it)
m[key] += Sum(*it);
return m[key];
}
}
// записываем в отображение все суммы: ключ - сумма
map<string, int> m;
Sum("root", m);
Здравствуйте, sadomovalex, Вы писали:
S>Здравствуйте, LexerCIT, Вы писали:
LCI>>надо выводить все суммы, а не какую-то одну, т.е. нужна рекурсивная процедура LCI>>в глав.ключах в поле суммы хранится null
S>Если предположить, что ключ корня дерева = "root", то с можно воспользоваться следующим псевдокодом: S>
Skipped
S>
Многие базы поддерживают рекурсивные запросы, например спец. синтаксис есть в Oracle и MaxDB. Возможно есть более простое (и более быстрое) решение, чем последовательный вызов селектов, портабельность конечно потеряется.