AXForum  
Вернуться   AXForum > Прочие обсуждения > Курилка
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 01.06.2012, 10:03   #1  
AP-1055D is offline
AP-1055D
Участник
 
351 / 92 (4) ++++
Регистрация: 01.06.2011
Как переписать запрос в DAX-выражение?
Коллеги,

Сейчас занимаюсь изучением BISM и DAX в SQL Server 2012. Возможно, у кого-нибудь есть опыт написания DAX-выражений.
Мне нужно переписать простой метод find на DAX:

select firstonly inventTrans
order by DatePhysical desc
where inventTrans.StatusReceipt == StatusReceipt::Purchased
&& inventTrans.ItemId == "";

return inventTrans.CustVendAC;

Проблема в том, что поле CustVendAC строкового типа и к нему нельзя применить агрегирующую функцию. Не мог бы кто-нибудь помочь мне, пожалуйста?
Старый 01.06.2012, 10:16   #2  
Murlin is offline
Murlin
Возьми свет!!!
Аватар для Murlin
Самостоятельные клиенты AX
Злыдни
 
291 / 32 (2) +++
Регистрация: 22.09.2008
Адрес: Тюмень, Рашан Федерашан
Цитата:
Сообщение от AP-1055D Посмотреть сообщение
Как переделать запрос в DAX выражение?
X++:
static str buildStringQuery(Query   query)
{
    int         i;
    str         result;
    ;
    for (i=1;i<=query.dataSourceCount();i++)
    {
        if (result)
            result = result + strfmt("\n");
        result = result + WorkFlowFunctions::buildDataSourceStr(query.dataSourceNo(i));
    }
    return result;
}
 
static str buildDataSourceStr(QueryBuildDataSource     qbds)
{
    container           c;
    str                 result = "";
    int                 i;
    str                 s,s1;
    boolean             whereB = false;
    tableName           tableName;
    tableName           newTableName;
    ;
    c = str2con_ru(qbds.toString()," WHERE ");
    s = conpeek(c,1);
    c = str2con_ru(s," NOTEXISTS JOIN ");
    s = conpeek(c,1);
    c = str2con_ru(s," EXISTST JOIN ");
    s = conpeek(c,1);
    c = str2con_ru(s," OUTER JOIN ");
    s = conpeek(c,1);
    c = str2con_ru(s," JOIN ");
    s = conpeek(c,1);
    s = s + " ";
    tableName = tableid2name(qbds.table());
    newTableName = strfmt("%1%2",tableName,qbds.uniqueId());
    s = strreplace(s,strfmt(" FROM %1 ",tableName),strfmt(" from %1 ",newTableName));
    if (qbds.linkCount())
    {
        s1 = WorkFlowFunctions::buildLinkStr(qbds);
        if ((s1) &&
            (!whereB))
        {
            s = s + strfmt(" where \n");
            whereB = true;
        }
        s = s + s1;
    }
    if (qbds.rangeCount())
    {
        s1 = WorkFlowFunctions::buildRangeStr(qbds);
        if ((s1) &&
            (!whereB))
        {
            s = s + strfmt(" where\n");
            whereB = true;
        }
        else
        if (s1)
            s = s + strfmt(" &&\n");
        s = s + s1;
    }
    if (qbds.id() > 1)
    {
        switch (qbds.joinMode())
        {
            case JoinMode::ExistsJoin:
                    s1 = " exists join ";
                    break;
            case JoinMode::InnerJoin:
                    s1 = " join ";
                    break;
            case JoinMode::NoExistsJoin:
                    s1 = " notexists join ";
                    break;
            case JoinMode::OuterJoin:
                    s1 = " outer join ";
                    break;
        }
        s = strreplace(s,"SELECT ",s1);
    }
    return s;
}
static str buildLinkStr(QueryBuildDataSource  qbds)
{
    int             i;
    str             s;
    str             result = "";
    QueryBuildLink  qbl;
    TableName       tableName;
    TableName       linkedTableName;
    TableName       newTableName;
    TableName       newLinkedTableName;
    container       c;
    ;
    if (qbds.id() > 1)
    {
        tableName = tableid2name(qbds.table());
        linkedTableName = tableid2name(qbds.parentDataSource().table());
        newTableName = strfmt("%1%2",tableName,qbds.uniqueId());
        newLinkedTableName = strfmt("%1%2",linkedTableName,qbds.parentDataSource().uniqueId());
        for (i=1;i<=qbds.linkCount();i++)
        {
            qbl = qbds.link(i);
            c = str2con_ru(qbl.toString(),"\\");
            s = conpeek(c,conlen(c));
            s = strreplace(s,tableName+".",newTableName+".");
            s = strreplace(s,linkedTableName+".",newLinkedTableName+".");
            if (result)
                result = result + strfmt(" &&\n");
            result = result + strfmt("(%1)",s);
        }
    }
    return result;
}
static str buildRangeStr(QueryBuildDataSource   qbds)
{
    int             i,j,iPos;
    str             result,res = "";
    QueryBuildRange qbr;
    str             fieldName,newFieldName;
    ListIterator    listIterator;
    str             s;
    ;
    for (i=1;i<=qbds.rangeCount();i++)
    {
        qbr =   qbds.range(i);
        if (qbr.value() == SysQuery::valueUnlimited())
            continue;
        fieldName = fieldid2name(qbds.table(),qbr.field());
        newFieldName = strfmt("%1%2.%3",tableid2name(qbds.table()),qbds.uniqueId(),fieldName);
        listIterator = new ListIterator(WorkFlowFunctions::processRange(qbr));
        result = "";
        while (listIterator.more())
        {
            if (result)
                result = result + " ";
            s = listIterator.value();
            if (s like "N'*'")
                result = result + s;
            else
            if (s == fieldName)
                result = result + newFieldName;
            else
            if (s == "OR")
                result = result + strfmt("||\n");
            else
            if (s == "NOT")
                result = result + "!";
            else
            if (s == "AND")
                result = result + strfmt("&&\n");
            else
            if (s == "=")
                result = result + "==";
            else
            if (fieldName2id(qbds.table(),s))
                result = result + strfmt("%1%2.%3",tableid2name(qbds.table()),qbds.uniqueId(),s);
            else
                result = result + s;
            listIterator.next();
        }
        if (res)
            res = res + strfmt(" &&\n");
        result = strreplace(result," N'","'");
        res = res + strfmt("(%1)",result);
    }
    return res;
}
Зачем это нужно сам не знаю
__________________
Axapta 3.0 sp 5 Oracle
Диплом Интернет-Университета Информационных Технологий: Основы бухгалтерского учета
Я могу взорвать вам мозг!!!
Старый 01.06.2012, 10:27   #3  
SRF is offline
SRF
Участник
MCBMSS
Axapta Retail User
 
375 / 562 (19) +++++++
Регистрация: 08.08.2007
Записей в блоге: 1
Цитата:
Сообщение от AP-1055D Посмотреть сообщение
Коллеги,

Сейчас занимаюсь изучением BISM и DAX в SQL Server 2012. Возможно, у кого-нибудь есть опыт написания DAX-выражений.
Мне нужно переписать простой метод find на DAX:

select firstonly inventTrans
order by DatePhysical desc
where inventTrans.StatusReceipt == StatusReceipt::Purchased
&& inventTrans.ItemId == "";

return inventTrans.CustVendAC;

Проблема в том, что поле CustVendAC строкового типа и к нему нельзя применить агрегирующую функцию. Не мог бы кто-нибудь помочь мне, пожалуйста?
Вы бы хоть написали, что DAX в первом и во втором случае = Data Analysis Expressions, а в третьем DAX = Dynamics AX, а то двоякое представление может быть )))))

А чем не устраивают функции min или max, они могут применяться и к строковым полям.
__________________
Sergey Nefedov

Последний раз редактировалось SRF; 01.06.2012 в 10:31.
Старый 01.06.2012, 10:33   #4  
AP-1055D is offline
AP-1055D
Участник
 
351 / 92 (4) ++++
Регистрация: 01.06.2011
SRF,

Да, я имел в виду именно Data Analysis Expressions.


Murlin,

Спасибо, за отклик!
Старый 01.06.2012, 10:36   #5  
AP-1055D is offline
AP-1055D
Участник
 
351 / 92 (4) ++++
Регистрация: 01.06.2011
SRF,

Функция MIN принимает аргумент, результатом вычисления которого являются числа или даты, и не может работать со значениями типа String.
Старый 01.06.2012, 10:48   #6  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Судя по документации в Data Analysis Expressions есть и TOPN и ORDER BY.

Т.е. вопрос сводится к тому как преобразовать табличную величину (пусть и состоящую из одной строки) в скалярную.
Старый 01.06.2012, 11:24   #7  
AP-1055D is offline
AP-1055D
Участник
 
351 / 92 (4) ++++
Регистрация: 01.06.2011
S.Kuskov,

Да, вопрос именно в этом: как преобразовать табличную переменную в скалярную.
Старый 01.06.2012, 11:41   #8  
AP-1055D is offline
AP-1055D
Участник
 
351 / 92 (4) ++++
Регистрация: 01.06.2011
S.Kuskov,

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

=CALCULATE(VALUES('InventTrans'[CustVendAC]); TOPN(1; FILTER('InventTrans'; 'InventTrans'[ItemId]=EARLIER('InventTrans'[ItemId])); 'InventTrans'[DatePhysical]; 0; 'InventTrans'[RecId]))

Следующий запрос возвращает пустое значение для всех строк, хотя в каждой строке указан поставщик:

=CALCULATE(VALUES('InventTrans'[CustVendAC]); TOPN(1; FILTER(VALUES('InventTrans'[CustVendAC]); 'InventTrans'[ItemId]=EARLIER('InventTrans'[ItemId])); 'InventTrans'[DatePhysical]; 0)).
Старый 01.06.2012, 11:48   #9  
S.Kuskov is offline
S.Kuskov
Участник
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
3,438 / 1775 (66) ++++++++
Регистрация: 28.04.2007
Адрес: Калуга
Цитата:
Сообщение от AP-1055D Посмотреть сообщение
Существует функция VALUES, с помощью которой можно получить определённый столбец таблицы.
В документации написано, что VALUE возврашает таблицу (состояшую из одного столбца), а не скаляр.
Возможно функция LOOKUPVALUE вам поможет
Старый 01.06.2012, 12:04   #10  
AP-1055D is offline
AP-1055D
Участник
 
351 / 92 (4) ++++
Регистрация: 01.06.2011
S.Kuskov,

Следующее выражение возвращает текущее значение CustVendAC:
=CALCULATE(VALUES('InventTrans'[CustVendAC])).

Я смотрел LOOKUPVALUE, но она оперирует только конкретными значениями при поиске, к тому же не понятно как в неё добавить TOPN.
Правда, я изучаю DAX всего несколько дней, поэтому чего-то могу не понимать.
Старый 04.06.2012, 12:41   #11  
AP-1055D is offline
AP-1055D
Участник
 
351 / 92 (4) ++++
Регистрация: 01.06.2011
Коллеги,

Спасибо всем за интерес к данной теме. Огромное спасибо за помощь Fec un Tues участнику форума SQL.ru!

Искомый запрос выглядит следующим образом:

=CALCULATE(FIRSTNONBLANK(InventTrans[CustVendAC]; 1); TOPN(1; FILTER('InventTrans'; 'InventTrans'[ItemId]=EARLIER('InventTrans'[ItemId])); 'InventTrans'[DatePhysical]; 0); FILTER('InventTrans'; 'InventTrans'[StatusReceipt]=1)).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Прайс на лицензии MS DAX UNRW Детская 1 08.09.2009 16:36
в качестве эксперимента теги dax* заменены на теги ax* mazzy Обсуждение форума 8 16.06.2009 13:16
Привествуем нового модератора в разделе DAX: DreamCreator mazzy Информация для участников 0 24.04.2009 15:59
Привествуем нового модератора в разделе DAX: sukhanchik mazzy Информация для участников 2 21.04.2009 21:31
Нужен сосед программист DAX для Совместного съема жилья :) Andrew Akhmetov Курилка 28 25.11.2008 17:53
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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