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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 20.05.2008, 14:45   #1  
Andrux is offline
Andrux
Участник
Axapta Retail User
 
263 / 17 (1) ++
Регистрация: 29.05.2007
Distinct в QueryBuildDataSource
Подскажите как с помощью QueryBuildDataSource реализовать запрос типа:

SELECT DISTINCT * FROM table
Старый 20.05.2008, 14:57   #2  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
Как заменить distinct?
За это сообщение автора поблагодарили: mazzy (2).
Старый 20.05.2008, 14:58   #3  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
смотрите в эту сторону
qbds.SortField(<Field>);
qbds.orderMode(orderMode::GroupBy);

получите запрос select Field from ... group by Field.

в чистом виде select distinct Field from ... в Аксапте вы не получите
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: mazzy (2).
Старый 20.05.2008, 15:26   #4  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Для того кому ОЧЕНЬ нужен distinct можно использовать notexists.
select t1
notexists join t2
where t2.Field1 == t1.Field1 && t2.Field2 == t1.Field2 && t2.RecId < t1.RecId
За это сообщение автора поблагодарили: kashperuk (3).
Старый 20.05.2008, 16:35   #5  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
по ситуации надо смотреть...

select Field from table group by Field
- это именно аналог
select distinct Field from table
всё-таки.

Один из возможных плюсов - возможность использовать индекс (если есть) по Field, для быстрой группировки, например, а вот в случае
select t1
notexists join t2
where t2.Field1 == t1.Field1 && t2.Field2 == t1.Field2 && t2.RecId < t1.RecId

поимеете полный перебор по таблице и ещё плюс доступ по индексу (если есть)...

В общем, нужно учитывать специфику запроса
__________________
Zhirenkov Vitaly
Старый 20.05.2008, 16:54   #6  
kashperuk is offline
kashperuk
Участник
Аватар для kashperuk
MCBMSS
Соотечественники
Сотрудники Microsoft Dynamics
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии 2011
Лучший по профессии 2009
 
4,361 / 2084 (78) +++++++++
Регистрация: 30.05.2004
Адрес: Atlanta, GA, USA
Вопрос к Wamr - а почему именно меньше (t2.RecId < t1.RecId) Я бы ожидал увидеть !=
Старый 20.05.2008, 17:02   #7  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от kashperuk Посмотреть сообщение
Вопрос к Wamr - а почему именно меньше (t2.RecId < t1.RecId) Я бы ожидал увидеть !=
Ну это стандартный приём, если вы поставите !=, то просто не получите никакого результата, если в таблице несколько записей с одинаковым Field1 && Field2 ...
А так вы задаёте определённую детерминированность и берёте строчку с наименьшим рекАйДи из всех...
(извините, что не Вамр :-х)
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: kashperuk (3).
Старый 21.05.2008, 00:35   #8  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
полностью согласен со всеми замечаниями Виталия, именно эти недостатки и прятались за словом ОЧЕНЬ
Старый 31.07.2009, 14:28   #9  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
И тут становиться такой вопрос: select count(OrderAccount) from purchTable group by OrderAccount; не вернет количество - поле строковое.... Вернет номер первого.

Для этих целей можно конечно написать так:

Query query = new Query();
QueryBuildDataSource purchTable_qbds = query.addDataSource(tableNum(PurchTable));
QueryRun queryRun;
;
purchTable_qbds.addSelectionField(fieldNum(Common, RecId), SelectionField::Count);
purchTable_qbds.addSortField(fieldNum(PurchTable, OrderAccount));
purchTable_qbds.orderMode(OrderMode::GroupBy);

queryRun = new QueryRun(query);

info(strfmt('%1', SysQuery::countTotal(queryRun)));

но, увы, это тот же перебор....
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
Старый 03.08.2009, 16:16   #10  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
Попрака к последнему посту: info(strfmt('%1', SysQuery::countTotal(queryRun))); вернет неверный результат, так как countTotal суммирует RecID, что приведет к полной ерунде

Поэтому лучше либо перебирать while(queryRun.next()) либо исхитряться:

X++:
select count(RecId) from vendTable
   exists join purchTable
       where purchTable.OrderAccount == vendTable.AccountNum
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
Старый 03.08.2009, 18:12   #11  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
plumbum, а в чём заключается ваш вопрос, если не секрет?
Вы этого хотите достичь?
(изьясняетесь уж больно непонятно...)
X++:
    purchTable  purchTable;
    ;
    while select count(recid) from purchTable
            group by OrderAccount
    {
        info(purchTable.OrderAccount);
        info(int2str(purchTable.RecId));
    }
SQL:
X++:
SELECT COUNT(A.RECID),A.ORDERACCOUNT FROM PURCHTABLE A WHERE (DATAAREAID=?) GROUP BY A.ORDERACCOUNT ORDER BY A.ORDERACCOUNT
__________________
Zhirenkov Vitaly
Старый 05.08.2009, 11:59   #12  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
Нет, в общем-то я хотел констатировать факт, что если суммировать по тому же полю, по которому группировать, то желаемого результата не будет.

Задача была выбрать количество разных поставщиков, для которых созданы закупки...
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
Старый 05.08.2009, 12:50   #13  
ZVV is offline
ZVV
MCITP
MCP
Oracle
MCBMSS
 
1,006 / 246 (11) ++++++
Регистрация: 13.02.2004
Адрес: Минск
->
Цитата:
Сообщение от plumbum Посмотреть сообщение
Нет, в общем-то я хотел констатировать факт, что если суммировать по тому же полю, по которому группировать, то желаемого результата не будет.

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

Вы пытались сделать вот такой запрос, вот выполните его и посмотрите, что выдаёт нормальный SQL, который вы хотели построить:
X++:
Select   orderaccount, count(orderaccount), count(*)
    From Purchtable
Group By orderaccount
Но из-за особенностие работы Аксапты с табличными переменными, вы не получите даже этого.

Вам же нужен один из следующих запросов:
X++:
Select Count ( Distinct Orderaccount )
  From Purchtable
/
Select Count ( * )
  From ( Select  Orderaccount
            From Purchtable
        Group By Orderaccount )
Ни того ни другого Аксапта не поддерживает, к сожалению.

Как вариант - воспользуйтесь direct sql.
Примерный код для 3-ки (тестировал на Оракле):
X++:
static void Job22(Args _args)
{
    dictTable   dictTable = new DictTable(tableNum(PurchTable));

    Connection  con  = new Connection();
    ResultSet   rs;
    Statement   stmt;

    str         sql;
    str         dataareaid;

    int         cnt;
    ;

    if (dictTable.dataPrCompany())
    {
        DataAreaId = curext();

        if ( SqlSystem::databaseBackendId() == DatabaseId::Oracle )
            dataareaid = strFmt(new SqlSystem().monocaseFmt(),dataareaid);
    }

     sql     = strFmt("Select Count ( Distinct %1 ) From %2 where %3 = \'%4\'",
                      dictTable.fieldName(fieldnum(PurchTable, OrderAccount), DBBackend::SQL),
                      dictTable.name(DbBackend::SQL),
                      dictTable.fieldName(fieldnum(PurchTable, DataAreaId), DBBackend::SQL),
                      DataAreaId);

    info(sql);

    stmt  = con.createStatement();
    rs    = stmt.executeQuery(sql);

    if (rs.next())
    {
        cnt = rs.getInt(1);
    }

    info(int2str(cnt));
}
На более поздних версия надо будет ещё включать разрешения через SqlStatementExecutePermission...
__________________
Zhirenkov Vitaly
За это сообщение автора поблагодарили: plumbum (1).
Старый 05.08.2009, 12:56   #14  
plumbum is offline
plumbum
Участник
Соотечественники
 
182 / 86 (3) ++++
Регистрация: 07.12.2007
Адрес: Vienna, AT
Спасибо, Виталий!
Но я бы предпочел workaround, как в случае с подключением справочника поставщиков. Все таки необходимо было решить локальную задачу.

2 kashperuk: А предвидиться в 6.0 какие-то похожие изменения в языке запросов AX?
__________________
http://www.axdevposts.blogspot.com
Пришел, уведел.... отойди, дай другому увидеть!
Теги
distinct, query, запрос (query)

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
QueryBuildDataSource - динамически if_maks DAX: Программирование 6 07.04.2006 13:39
Как заменить distinct? Zeratul DAX: Программирование 4 21.10.2005 16:10
Непонятное поведение векторных полей в QueryBuildDataSource. Lemming DAX: Программирование 2 12.05.2005 17:43
Вопрос по QueryBuildDataSource, QueryBuildRange и QueryRun Paul_ST DAX: Программирование 9 11.02.2004 17:13
Помогите разобраться с QueryBuildDataSource raz DAX: Программирование 10 04.09.2003 12:03

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

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

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