AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 24.05.2013, 15:55   #1  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
! 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));
}
Он выдаёт такой sql запрос:
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
который я подправил, чтобы проверить в sqlms


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
В sqlms он отрабатывает и выдаёт результаты.

Прошу помочь или подтолкнуть в нужную сторону, куда копать. Спасибо заранее.

С уважением.



Нашёл на форуме в теме такую фразу

Цитата:
Сообщение от Wamr Посмотреть сообщение
В SQL при использовании GROUP BY нельзя получить данные, которые не входят в список агрегирующих полей (addSortField) или функций (SelectionField).
Так что Аксапта тут не виновата
Добавил нужные мне поля, которые хочу выбрать из данной таблицы - ничего(

Последний раз редактировалось user_ax; 24.05.2013 в 16:02.
Старый 24.05.2013, 16:03   #2  
ice is offline
ice
Участник
Аватар для ice
Лучший по профессии 2014
 
1,731 / 406 (17) +++++++
Регистрация: 23.03.2006
зачем эта строка?
X++:
qbds_vendinvoicetrans.addSortField([COLOR=blue]fieldnum[/COLOR](VendInvoiceTrans,Qty));
За это сообщение автора поблагодарили: S.Kuskov (1).
Старый 24.05.2013, 16:14   #3  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от user_ax Посмотреть сообщение
ничего не выходит.
это значит запрос возвращается пустым или что-то возвращает, но не то что хотелось бы?

Цитата:
Сообщение от user_ax Посмотреть сообщение
X++:
qbds_vendinvoicetrans.addSortField(fieldnum(VendInvoiceTrans,Qty));
Эта строчка у вас для чего?
Как можно одновременно суммировать и группировать по одному и тому же полю?

Вы подчинённые таблицы цепляете только для фильтрации основной или для выборки из них каких-то полей?

Последний раз редактировалось S.Kuskov; 24.05.2013 в 16:17.
Старый 24.05.2013, 16:15   #4  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от ice Посмотреть сообщение
зачем эта строка?
X++:
qbds_vendinvoicetrans.addSortField([COLOR=blue]fieldnum[/COLOR](VendInvoiceTrans,Qty));
Я процитировал человека выше, который сказал, что нельзя в group by получить данные, которые не входят в список полей, по которым делаются агрегирующие ф-ции.
Если её убрать - ничего не меняется.
Старый 24.05.2013, 16:17   #5  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
это значит запрос возвращается пустым или что-то возвращает, но не то что хотелось бы?


Эта строчка у вас для чего?

Вы подчинённые таблицы цепляете только для фильтрации основной или для выборки из них каких-то полей?
Запрос возращается без нужных мне полей, выводится только поля из 1 таблицы и то вместо значений выводятся 0.


Цепляю для выборки из них полей.

Последний раз редактировалось user_ax; 24.05.2013 в 16:19.
Старый 24.05.2013, 16:22   #6  
ice is offline
ice
Участник
Аватар для ice
Лучший по профессии 2014
 
1,731 / 406 (17) +++++++
Регистрация: 23.03.2006
Цитата:
Сообщение от user_ax Посмотреть сообщение
Запрос возращается без нужных мне полей, выводится только поля из 1 таблицы и то вместо значений выводятся 0.


Цепляю для выборки из них полей.
у вас по первой таблице группировка, все присоединенные таблицы могут показать поля, только если поля эти добавите в группировку
Старый 24.05.2013, 16:23   #7  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от ice Посмотреть сообщение
у вас по первой таблице группировка, все присоединенные таблицы могут показать поля, только если поля эти добавите в группировку

То есть, мне нужно для двух остальных qbds прописать addSortField с теми полями, которые мне нужно вывести ?
Старый 24.05.2013, 16:31   #8  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от user_ax Посмотреть сообщение
Цепляю для выборки из них полей.
Вы дважды "цепляете" поле Qty. Один раз в список агрегирующих функций
X++:
qbds_vendinvoicetrans.addSelectionField(fieldnum(VendInvoiceTrans,Qty), SelectionField::Sum);
а второй раз в список полей по которым идёт группировка
X++:
qbds_vendinvoicetrans.addSortField(fieldnum(VendInvoiceTrans,Qty));
Второе излишне. Более того оно искажает весь смысл группировки.

Вам по смыслу нужно складывать количество в разрезе каких-то групп полей? Каких?
Старый 24.05.2013, 16:32   #9  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Уважаемый ice , а скажите, пожалуйста, к какому Qbds цеплять поля ? попробовал к дочерним, из которых надо выводить - не сработало. Если цепляю к главному , пишет - Недопустимое поле сортировки , что в принципе понятно, так как таких полей нет в главной таблице.
Старый 24.05.2013, 16:33   #10  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
Вы дважды "цепляете" поле Qty. Один раз в список агрегирующих функций
X++:
qbds_vendinvoicetrans.addSelectionField(fieldnum(VendInvoiceTrans,Qty), SelectionField::Sum);
а второй раз в список полей по которым идёт группировка
X++:
qbds_vendinvoicetrans.addSortField(fieldnum(VendInvoiceTrans,Qty));
Второе излишне. Более того оно искажает весь смысл группировки.

Вам по смыслу нужно складывать количество в разрезе каких-то групп полей? Каких?
Да, это я уже осознал и убрал второй раз поле qty.

Да, вы правы, мне нужно искать сумму поля qty в разрезе полей itemid && internalsp.
Старый 24.05.2013, 16:40   #11  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от user_ax Посмотреть сообщение
Да, вы правы, мне нужно искать сумму поля qty в разрезе полей itemid && internalsp.
У вас поля InternalSp и ItemId находятся в той же таблице, что и qty. Зачем вам остальные таблицы. Скорее всего полей в группировке больше?

В аксапте нельзя сначала сгруппировать одну таблицу, а потом к группированной таблице присоеденить не группированную подчинённую. В аксапте сначала выполняются все соединения, а потом уже происходит группировка результирующего соединения.

Можно иначе, но для этого нужно создавать промежуточные View.
Старый 24.05.2013, 16:46   #12  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от S.Kuskov Посмотреть сообщение
У вас поля InternalSp и ItemId находятся в той же таблице, что и qty. Зачем вам остальные таблицы. Скорее всего полей в группировке больше?

В аксапте нельзя сначала сгруппировать одну таблицу, а потом к группированной таблице присоеденить не группированную подчинённую. В аксапте сначала выполняются все соединения, а потом уже происходит группировка результирующего соединения.

Можно иначе, но для этого нужно создавать промежуточные View.
Да, в одной и той же, но по ним нужно присоединять другие таблицы и брать из них информацию для отчёта.

То есть нужно сначала подобавлять критерии, условия, а в конце query добавить группировку и подсчёт суммы ?
Старый 24.05.2013, 16:47   #13  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Я вот думаю сделать это через While select что ли...

Нужно реализовать следующее:

Цитата:
Для отобранных строк из VendSpListJour и VendSpListTrans следует отбирать строки в VendInvoiceTrans (связь по полю VendSpListTrans.InternalSp), группировать поле Qty по ItemId и InternalSp, и выводить в виде отчёта, как описано ниже. Если в VendInvoiceTrans строк с соответствующим значением InternalSp не найдено, то соответствующая (правая) часть отчёта останется незаполненной.
Старый 24.05.2013, 16:57   #14  
maldini is offline
maldini
Участник
 
103 / 30 (2) +++
Регистрация: 06.03.2007
Адрес: москва
Странно! Каким способом ты получаешь данные из запроса.
Вот такой пример работает без проблем
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   #15  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от 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);
    }
}
В вашем запросе вы к одному Qbds цепляете разные таблицы, а у меня к каждому свою.
Как всё-таки правильно?
У меня связи таблиц немного другие

ListJour => ListTrans - один ко многим
ListTrans => VendInvoiceTrans - много ко многим.
Может быть из-за этого проблема?
Старый 24.05.2013, 17:07   #16  
maldini is offline
maldini
Участник
 
103 / 30 (2) +++
Регистрация: 06.03.2007
Адрес: москва
Цитата:
Сообщение от user_ax Посмотреть сообщение
В вашем запросе вы к одному Qbds цепляете разные таблицы, а у меня к каждому свою.
Как всё-таки правильно?
У меня связи таблиц немного другие

ListJour => ListTrans - один ко многим
ListTrans => VendInvoiceTrans - много ко многим.
Может быть из-за этого проблема?
QDBS тут совсем не причем. Всеравно все от query идет. Просто в вашем случае можно в любое место добавить какое либо условия, а в моем придется в переменную qdbs предварительно получить datasource того запроса куда буду добовлять фильтр, вот так
X++:
qdbs = query.dataSourceTable(tableNum(VendInvoiceJour));
Условия соединений я думаю тут не причем, если из моего примера убрать
X++:
qbds.joinMode(JoinMode::InnerJoin);
все так же будет работать проблема где то близко. )))

Последний раз редактировалось maldini; 24.05.2013 в 17:12.
Старый 24.05.2013, 17:11   #17  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от maldini Посмотреть сообщение
QDBS тут совсем не причем. Всеравно все от query идет. Просто в вашем случае можно в любое место добавить какое либо условия, а в моем придется в переменную qdbs предварительно получить datasource того запроса куда буду добовлять фильтр, вот так
X++:
qdbs = query.dataSourceTable(tableNum(VendInvoiceJour));
Сейчас попробую переписать по вашему примеру, спасибо. Посмотрим как будет.
Старый 24.05.2013, 17:14   #18  
maldini is offline
maldini
Участник
 
103 / 30 (2) +++
Регистрация: 06.03.2007
Адрес: москва
Цитата:
Сообщение от user_ax Посмотреть сообщение
Сейчас попробую переписать по вашему примеру, спасибо. Посмотрим как будет.
По твоему примеру мне кажется тоже все работает, пришли пример как ты вынимаешь значения из query
Старый 24.05.2013, 17:16   #19  
user_ax is offline
user_ax
Участник
Аватар для user_ax
 
599 / 39 (3) +++
Регистрация: 07.10.2012
Адрес: ZP
Цитата:
Сообщение от maldini Посмотреть сообщение
По твоему примеру мне кажется тоже все работает, пришли пример как ты вынимаешь значения из query
В теле отчёта делаю
X++:
 queryRun = this.main_query();

    while(queryRun.next())
    {
        vendsp = queryRun.get(tablenum(VendSpListJour));
        vendsplist = queryRun.get(tablenum(VendSpListTrans));
        vendinvoice = queryRun.get(tablenum(VendInvoiceTrans));
Если вы это имели ввиду.
Старый 24.05.2013, 17:17   #20  
maldini is offline
maldini
Участник
 
103 / 30 (2) +++
Регистрация: 06.03.2007
Адрес: москва
Цитата:
Сообщение от user_ax Посмотреть сообщение
В теле отчёта делаю
X++:
 queryRun = this.main_query();
 
    while(queryRun.next())
    {
        vendsp = queryRun.get(tablenum(VendSpListJour));
        vendsplist = queryRun.get(tablenum(VendSpListTrans));
        vendinvoice = queryRun.get(tablenum(VendInvoiceTrans));
Если вы это имели ввиду.
А зачем так много таблиц, ведь данные, если я не ошибаюсь будут только в VendInvoiceTrans. Для того что бы получить значения полей из других таблиц их надо тоже включать в группировку. Вот пример как получить значение закупки из другой таблицы, если группировку не делать то она будет пустой.
X++:
void main_query(boolean _count_query = false)
{
    VendInvoiceJour     VendInvoiceJour;
    VendInvoiceTrans    VendInvoiceTrans;
    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.addRange(fieldnum(VendInvoiceJour,purchId)).value('Номер закупки');
    qbds  = qbds.addDataSource(tablenum(VendInvoiceTrans));
    qbds.addSortField(fieldnum(VendInvoiceTrans,purchId));
    qbds.orderMode(OrderMode::GroupBy);
    qbds.addLink(fieldnum(VendInvoiceJour,purchId),fieldnum(VendInvoiceTrans,purchId));

    QueryRun = new QueryRun(query);
    while (queryRun.next())
    {
        VendInvoiceJour = QueryRun.get(tablenum(VendInvoiceJour));
        VendInvoiceTrans    = QueryRun.get(tablenum(VendInvoiceTrans));
        info(strFmt("%1  %2",VendInvoiceJour.PurchId,VendInvoiceJour.Qty));
        info(strFmt("%1",VendInvoiceTrans.PurchId));
    }
}

Последний раз редактировалось maldini; 24.05.2013 в 17:44.
Теги
group by, query, группировка

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
AX 2012 Наследование таблиц. Краткое описание механизма sukhanchik DAX: Программирование 32 21.09.2018 17:56
emeadaxsupport: Calling the Query Service Blog bot DAX Blogs 0 18.02.2012 01:13
AIF: OData Query Service Blog bot DAX Blogs 0 24.08.2011 09:11
jinx: Dynamics AX – Query-Ranges und Filtereinstellungen des Benutzers Blog bot DAX auf Deutsch 0 04.02.2010 00:05
Dynamics AX Geek: Using query() Blog bot DAX Blogs 0 04.05.2009 14:05

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 18:53.