|
02.04.2008, 15:56 | #1 |
Участник
|
Суммы по двум таблицам
Всем привет!
Есть задача посчитать суммы в двух связанных(1:n) таблицах сгруппировав их по полю. такой запрос приводит к неправильному результату, т.е. суммы в первой таблице считаются несколько раз (сколько записей во второй): X++: while select sum(LineAmount) from Table1 group by Table1.ItemId join sum(Qty), sum(CostAmount) from Table2 where Table1.Id = Table2.Id |
|
02.04.2008, 16:17 | #2 |
MCITP
|
По-моему, никак. Делайте вложенными циклами...
__________________
Zhirenkov Vitaly |
|
03.04.2008, 11:39 | #3 |
NavAx
|
X++: static void JobTest(Args _args) { InventTrans InventTrans; InventJournalTrans InventJournalTrans; ; select sum(Qty), count(RecId) from InventTrans group by TransRefId join sum(Qty), sum(CostAmount) from InventJournalTrans where InventJournalTrans.InventTransId == InventTrans.InventTransId && InventJournalTrans.JournalId == "СЖ00546541"; info(strfmt("%1 %2 %3 %4",InventTrans.Qty, InventTrans.RecId, InventJournalTrans.Qty, InventJournalTrans.CostAmount)); } -9 720,00 2 -9 720,00 -57 639,60 |
|
03.04.2008, 12:09 | #4 |
MCITP
|
2 raz: Извини, но пример "ни о чём" в контексте имеющегося вопроса.
В приведённом примере связь похоже 1 к 1-му. А нужно 1 ко многим. И группировка должна быть на "таблице-шапке". Вот пример raz, не работающий на правильных данных и мой вариант решения исходной задачи: X++: static void ZVVJobTest(Args _args) { InventTrans InventTrans; InventJournalTrans InventJournalTrans, InventJournalTransIn; ; // Журнал "УЗЖ001779" // В нём одна строка с кол-вом 10 (цена 20, сумма 200) // По ней 2 проводки с кол-вом 5 в каждой select sum(Qty), count(RecId) from InventTrans group by TransRefId join sum(Qty), sum(CostAmount), count(RecId) from InventJournalTrans where InventJournalTrans.InventTransId == InventTrans.InventTransId && InventJournalTrans.JournalId == "УЗЖ001779"; info(strfmt("Неверно! Проводка: %1 %2 Строка: %3 %4 %5",InventTrans.Qty, InventTrans.RecId, InventJournalTrans.Qty, InventJournalTrans.RecId, InventJournalTrans.CostAmount)); while Select sum(Qty), sum(CostAmount), count(RecId) from InventJournalTrans group by ItemId where InventJournalTrans.JournalId == "УЗЖ001779" { // Второй Джоин строк журнала для демонстрации общего случая, когда нет группируемого поля во второй таблице // (возможно в некотрых случаях по смыслу он и не нужен!) select sum(Qty), count(RecId) from InventTrans join count(recid) from InventJournalTransIn where InventJournalTransIn.InventTransId == InventTrans.InventTransId && InventJournalTransIn.JournalId == "УЗЖ001779" && InventJournalTransIn.ItemId == InventJournalTrans.ItemId; info(strfmt("Верно! Проводка: %1 %2 Строка: %3 %4 %5",InventTrans.Qty, InventTrans.RecId, InventJournalTrans.Qty, InventJournalTrans.RecId, InventJournalTrans.CostAmount)); } } Неверно! Проводка: 10,00 2 Строка: 20,00 2 400,00 Верно! Проводка: 10,00 2 Строка: 10,00 1 200,00
__________________
Zhirenkov Vitaly Последний раз редактировалось ZVV; 03.04.2008 в 12:13. Причина: Сорри, ошибка закралась в коде :) |
|
03.04.2008, 14:50 | #5 |
Участник
|
к сожалению исходная задача вложенными запросами не решается, тк запрос создается динамически, приведенный мной пример лишь частный случай, сам запрос можетбыть гораздо сложней (множество группировок, джойнов, фильтров)
|
|
03.04.2008, 16:37 | #6 |
MCITP
|
Ну боюсь, что тем не менее придётся что-то менять в вашей динамике.
В аксапте одним запросом вы такое не сможете изобразить. По крайней мере, мне в голову ничего не приходит. В оракле ещё можно было бы через аналитические функции выкрутиться, но и то, это получится такой навороченный и нечитаемый селект в вашем случае "(множество группировок, джойнов, фильтров) "...
__________________
Zhirenkov Vitaly |
|
09.04.2008, 13:01 | #7 |
Developer
|
|
|
09.04.2008, 13:10 | #8 |
Участник
|
|
|
09.04.2008, 14:23 | #9 |
Developer
|
Не понял.
Я имел в виду что запрос вида Код: select ... from Table1, (select id, ... from Table2 group by id) as Table2 where Table1.id = Tablt2.id [group by ...] Вот только на практике зачастую это лишнее... |
|
09.04.2008, 14:32 | #10 |
Участник
|
|
|
09.04.2008, 14:43 | #11 |
Developer
|
|
|
10.04.2008, 11:58 | #12 |
Участник
|
Всем большое спасибо за участие!
Проблему решил с использованием временной таблицы |
|
10.04.2008, 14:42 | #13 |
Участник
|
зачем временная таблица? лучше используйте класс KeySum
|
|
10.04.2008, 15:21 | #14 |
Участник
|
|
|
25.04.2008, 12:59 | #15 |
Участник
|
а что собственно делает класс KeySum?
|
|
28.04.2008, 15:53 | #16 |
Участник
|
Сохраняет и модифицирует набор чисел, позволяя обращаться к каждому из них по "ключу". Т.е. не просто по номеру (как в массиве), но по некоему идентификатору. Как правило, символьному, но тип идентификатора может быть любым. В частности, и числом.
При этом, имеется возможность (при желании) упорядочивать элементы набора по значению ключа, а также подсчитывать итоговую сумму всех числовых данных. Также можно организовать хранение "многомерных" чисел. Т.е. каждое "число" может представляться контейнером из набора чисел. Основной метод inventSum.updateNow() прибавляет к указанному элементу указанное значение. Используется для хранения промежуточных результатов расчета и "накопительных" значений. В смысле суммы, получающейся в результате прогона некоего цикла, где сумма увеличивается на значение, вычисляемое в теле цикла. |
|
|
За это сообщение автора поблагодарили: Qaz Qwerty (1). |