|
24.05.2013, 15:55 | #1 |
Участник
|
Query для 3-х таблиц с группировкой.
Есть задача: построить отчёт на основании 3-х таблиц с определёнными условиями. Условия пока опустим. Нужно объединить 3 таблицы между собой с помощью query. Второй день бьюсь, как только не соединял - ничего не выходит.
Последняя версия такова: X++: Queryrun main_query(boolean _count_query = false) { Query query = new Query(); QueryBuildDataSource qbds_vendsplistjour, qbds_vendsplisttrans, qbds_vendinvoicetrans; QueryBuildRange qbr; ; qbds_vendinvoicetrans = query.addDataSource(tablenum(VendInvoiceTrans)); qbds_vendinvoicetrans.addSelectionField(fieldnum(VendInvoiceTrans,Qty), SelectionField::Sum); qbds_vendinvoicetrans.orderMode(OrderMode::GroupBy); qbds_vendinvoicetrans.addSortField(fieldnum(VendInvoiceTrans,ItemId)); qbds_vendinvoicetrans.addSortField(fieldnum(VendInvoiceTrans,InternalSp)); qbds_vendinvoicetrans.addSortField(fieldnum(VendInvoiceTrans,Qty)); qbds_vendsplisttrans = qbds_vendinvoicetrans.addDataSource(tablenum(VendSpListTrans)); qbds_vendsplisttrans.addLink(fieldnum(VendInvoiceTrans,InternalSp),fieldnum(VendSpListTrans,InternalSp)); qbds_vendsplistjour = qbds_vendsplisttrans.addDataSource(tablenum(VendSpListJour)); qbds_vendsplistjour.relations(true); if (_count_query) { qbds_vendinvoicetrans.addSelectionField(fieldnum(VendInvoiceTrans,Recid),SelectionField::Count); } info(qbds_vendinvoicetrans.toString()); return (new QueryRun(query)); } X++: SELECT FIRSTFAST SUM(Qty), COUNT(RecId) FROM VendInvoiceTrans GROUP BY VendInvoiceTrans.ItemId ASC, VendInvoiceTrans.InternalSp ASC, VendInvoiceTrans.Qty ASC JOIN FIRSTFAST * FROM VendSpListTrans WHERE VendInvoiceTrans.InternalSp = VendSpListTrans.InternalSp JOIN FIRSTFAST * FROM VendSpListJour WHERE VendSpListTrans.InternalSp = VendSpListJour.InternalSp X++: SELECT SUM(VendInvoiceTrans.Qty), COUNT(VendInvoiceTrans.RecId) FROM VendInvoiceTrans JOIN VendSpListTrans on VendInvoiceTrans.InternalSp = VendSpListTrans.InternalSp JOIN VendSpListJour on VendSpListTrans.InternalSp = VendSpListJour.InternalSp --GROUP BY VendInvoiceTrans.ItemId , -- VendInvoiceTrans.InternalSp Прошу помочь или подтолкнуть в нужную сторону, куда копать. Спасибо заранее. С уважением. Нашёл на форуме в теме такую фразу Добавил нужные мне поля, которые хочу выбрать из данной таблицы - ничего( Последний раз редактировалось user_ax; 24.05.2013 в 16:02. |
|
24.05.2013, 16:03 | #2 |
Участник
|
зачем эта строка?
X++: qbds_vendinvoicetrans.addSortField([COLOR=blue]fieldnum[/COLOR](VendInvoiceTrans,Qty)); |
|
|
За это сообщение автора поблагодарили: S.Kuskov (1). |
24.05.2013, 16:15 | #3 |
Участник
|
Цитата:
Если её убрать - ничего не меняется. |
|
24.05.2013, 16:14 | #4 |
Участник
|
это значит запрос возвращается пустым или что-то возвращает, но не то что хотелось бы?
Цитата:
Как можно одновременно суммировать и группировать по одному и тому же полю? Вы подчинённые таблицы цепляете только для фильтрации основной или для выборки из них каких-то полей? Последний раз редактировалось S.Kuskov; 24.05.2013 в 16:17. |
|
24.05.2013, 16:17 | #5 |
Участник
|
Цитата:
Цепляю для выборки из них полей. Последний раз редактировалось user_ax; 24.05.2013 в 16:19. |
|
24.05.2013, 16:22 | #6 |
Участник
|
у вас по первой таблице группировка, все присоединенные таблицы могут показать поля, только если поля эти добавите в группировку
|
|
24.05.2013, 16:23 | #7 |
Участник
|
|
|
24.05.2013, 16:31 | #8 |
Участник
|
Вы дважды "цепляете" поле Qty. Один раз в список агрегирующих функций
X++: qbds_vendinvoicetrans.addSelectionField(fieldnum(VendInvoiceTrans,Qty), SelectionField::Sum); X++: qbds_vendinvoicetrans.addSortField(fieldnum(VendInvoiceTrans,Qty)); Вам по смыслу нужно складывать количество в разрезе каких-то групп полей? Каких? |
|
24.05.2013, 16:33 | #9 |
Участник
|
Цитата:
Сообщение от S.Kuskov
Вы дважды "цепляете" поле Qty. Один раз в список агрегирующих функций
X++: qbds_vendinvoicetrans.addSelectionField(fieldnum(VendInvoiceTrans,Qty), SelectionField::Sum); X++: qbds_vendinvoicetrans.addSortField(fieldnum(VendInvoiceTrans,Qty)); Вам по смыслу нужно складывать количество в разрезе каких-то групп полей? Каких? Да, вы правы, мне нужно искать сумму поля qty в разрезе полей itemid && internalsp. |
|
24.05.2013, 16:40 | #10 |
Участник
|
Цитата:
В аксапте нельзя сначала сгруппировать одну таблицу, а потом к группированной таблице присоеденить не группированную подчинённую. В аксапте сначала выполняются все соединения, а потом уже происходит группировка результирующего соединения. Можно иначе, но для этого нужно создавать промежуточные View. |
|
24.05.2013, 16:32 | #11 |
Участник
|
Уважаемый ice , а скажите, пожалуйста, к какому Qbds цеплять поля ? попробовал к дочерним, из которых надо выводить - не сработало. Если цепляю к главному , пишет - Недопустимое поле сортировки , что в принципе понятно, так как таких полей нет в главной таблице.
|
|
24.05.2013, 16:47 | #12 |
Участник
|
Я вот думаю сделать это через While select что ли...
Нужно реализовать следующее: Цитата:
Для отобранных строк из VendSpListJour и VendSpListTrans следует отбирать строки в VendInvoiceTrans (связь по полю VendSpListTrans.InternalSp), группировать поле Qty по ItemId и InternalSp, и выводить в виде отчёта, как описано ниже. Если в VendInvoiceTrans строк с соответствующим значением InternalSp не найдено, то соответствующая (правая) часть отчёта останется незаполненной.
|
|
24.05.2013, 16:57 | #13 |
Участник
|
Странно! Каким способом ты получаешь данные из запроса.
Вот такой пример работает без проблем X++: Queryrun main_query(boolean _count_query = false) { VendInvoiceJour VendInvoiceJour; QueryRun QueryRun; Query query = new Query(); QueryBuildDataSource qbds; QueryBuildRange qbr; ; qbds = query.addDataSource(tablenum(VendInvoiceJour)); qbds.addSortField(fieldnum(VendInvoiceJour,purchId)); qbds.addSelectionField(fieldnum(VendInvoiceJour,Qty), SelectionField::Sum); qbds.orderMode(OrderMode::GroupBy); qbds = qbds.addDataSource(tablenum(VendInvoiceTrans)); qbds.addLink(fieldnum(VendInvoiceJour,purchId),fieldnum(VendInvoiceTrans,purchId)); qbds.joinMode(JoinMode::InnerJoin); qbds = query.dataSourceTable(tableNum(VendInvoiceJour)); QueryRun = new QueryRun(query); while (queryRun.next()) { VendInvoiceJour = QueryRun.get(tablenum(VendInvoiceJour)); info(strFmt("%1 %2",VendInvoiceJour.PurchId,VendInvoiceJour.Qty); } } |
|
24.05.2013, 17:02 | #14 |
Участник
|
Цитата:
Сообщение от maldini
Странно! Каким способом ты получаешь данные из запроса.
Вот такой пример работает без проблем X++: Queryrun main_query(boolean _count_query = false) { VendInvoiceJour VendInvoiceJour; QueryRun QueryRun; Query query = new Query(); QueryBuildDataSource qbds; QueryBuildRange qbr; ; qbds = query.addDataSource(tablenum(VendInvoiceJour)); qbds.addSortField(fieldnum(VendInvoiceJour,purchId)); qbds.addSelectionField(fieldnum(VendInvoiceJour,Qty), SelectionField::Sum); qbds.orderMode(OrderMode::GroupBy); qbds = qbds.addDataSource(tablenum(VendInvoiceTrans)); qbds.addLink(fieldnum(VendInvoiceJour,purchId),fieldnum(VendInvoiceTrans,purchId)); qbds.joinMode(JoinMode::InnerJoin); qbds = query.dataSourceTable(tableNum(VendInvoiceJour)); QueryRun = new QueryRun(query); while (queryRun.next()) { VendInvoiceJour = QueryRun.get(tablenum(VendInvoiceJour)); info(strFmt("%1 %2",VendInvoiceJour.PurchId,VendInvoiceJour.Qty); } } Как всё-таки правильно? У меня связи таблиц немного другие ListJour => ListTrans - один ко многим ListTrans => VendInvoiceTrans - много ко многим. Может быть из-за этого проблема? |
|
24.05.2013, 17:07 | #15 |
Участник
|
Цитата:
X++: qdbs = query.dataSourceTable(tableNum(VendInvoiceJour)); X++: qbds.joinMode(JoinMode::InnerJoin); Последний раз редактировалось maldini; 24.05.2013 в 17:12. |
|
24.05.2013, 17:11 | #16 |
Участник
|
Цитата:
Сообщение от maldini
QDBS тут совсем не причем. Всеравно все от query идет. Просто в вашем случае можно в любое место добавить какое либо условия, а в моем придется в переменную qdbs предварительно получить datasource того запроса куда буду добовлять фильтр, вот так
X++: qdbs = query.dataSourceTable(tableNum(VendInvoiceJour)); |
|
24.05.2013, 17:26 | #17 |
Участник
|
Если джойнить 2 таблицы - всё замечательно, когда пытаюсь приджойнить третью - qbds валится в null.
X++: Queryrun main_query(boolean _count_query = false) { Query query = new Query(); QueryBuildDataSource qbds; ; qbds = query.addDataSource(tablenum(VendInvoiceTrans)); qbds.addSortField(fieldnum(VendInvoiceTrans,ItemId)); qbds.addSortField(fieldnum(VendInvoiceTrans,InternalSp)); qbds.addSelectionField(fieldnum(VendInvoiceTrans,Qty), SelectionField::Sum); qbds.orderMode(OrderMode::GroupBy); qbds = qbds.addDataSource(tablenum(VendSpListTrans)); qbds.addLink(fieldnum(VendSpListTrans,InternalSp),fieldnum(VendInvoiceTrans,InternalSp)); qbds.joinMode(JoinMode::InnerJoin); qbds = query.dataSourceTable(tableNum(VendSpListJour)); qbds.addLink(fieldnum(VendSpListTrans,InternalSp),fieldnum(VendSpListJour,InternalSP)); qbds.joinMode(JoinMode::InnerJoin); if (datefromstr && datetostr) { qbds.addRange(fieldnum(VendSpListJour,SpDate)).value(SysQuery::range(datefrom.value(),dateto.value())); } if (vendaccountstr) { qbds.addRange(fieldnum(VendSpListJour,OrderAccount)).value(SysQuery::value(vendaccountstr)); } //если введён регистранионный номер договора if (rcontractaccountstr) { qbds.addRange(fieldnum(VendSpListJour, RcontractAccount)).value(SysQuery::value(rcontractaccount.value())); } //если введён Владелец if (emplidstr) { qbds.addRange(fieldnum(VendSpListJour, Emplid)).value(SysQuery::value(emplid.value())); } switch(spclosedstr) { case (AllOpenPosted::All): qbds.addRange(fieldnum(VendSpListJour,SpClosed)); break; case (AllOpenPosted::Open): qbds.addRange(fieldnum(VendSpListJour,SpClosed)).value('1'); break; case (AllOpenPosted::Posted): qbds.addRange(fieldnum(VendSpListJour,SpClosed)).value('0'); break; default: break; } qbds = query.dataSourceTable(tablenum(VendInvoiceTrans)); if (_count_query) { qbds.addSelectionField(fieldnum(VendinvoiceTrans,RecId), SelectionField::Count); } qbds = query.dataSourceTable(tablenum(VendSpListTrans)); return (new QueryRun(query)); } qbds.addLink(fieldnum(VendSpListTrans,InternalSp),fieldnum(VendSpListJour,InternalSP)); Если заккоментировать весь кусок от qbds = query.dataSourceTable(tableNum(VendSpListJour)); и до конца switch - всё замечательно работает. Уважаемый maldini, не знаете, в чём причина? |
|
24.05.2013, 17:29 | #18 |
Участник
|
А, я понял, я не добавляю датасорс, я пытаюсь узнать его id
|
|
24.05.2013, 17:39 | #19 |
Участник
|
если я вас правильно понял, то вам не сделать это одним запросом. делайте while select по двум таблицам, и в цикле группировку по VendInvoiceTrans
|
|
24.05.2013, 17:42 | #20 |
Участник
|
|
|
Теги |
group by, query, группировка |
|
|