01.06.2012, 10:03 | #1 |
Участник
|
Как переписать запрос в 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 |
Возьми свет!!!
|
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 |
Участник
|
Цитата:
Сообщение от 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 строкового типа и к нему нельзя применить агрегирующую функцию. Не мог бы кто-нибудь помочь мне, пожалуйста? А чем не устраивают функции min или max, они могут применяться и к строковым полям.
__________________
Sergey Nefedov Последний раз редактировалось SRF; 01.06.2012 в 10:31. |
|
01.06.2012, 10:33 | #4 |
Участник
|
SRF,
Да, я имел в виду именно Data Analysis Expressions. Murlin, Спасибо, за отклик! |
|
01.06.2012, 10:36 | #5 |
Участник
|
SRF,
Функция MIN принимает аргумент, результатом вычисления которого являются числа или даты, и не может работать со значениями типа String. |
|
01.06.2012, 10:48 | #6 |
Участник
|
|
|
01.06.2012, 11:24 | #7 |
Участник
|
S.Kuskov,
Да, вопрос именно в этом: как преобразовать табличную переменную в скалярную. |
|
01.06.2012, 11:41 | #8 |
Участник
|
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 |
Участник
|
Цитата:
Возможно функция LOOKUPVALUE вам поможет |
|
01.06.2012, 12:04 | #10 |
Участник
|
S.Kuskov,
Следующее выражение возвращает текущее значение CustVendAC: =CALCULATE(VALUES('InventTrans'[CustVendAC])). Я смотрел LOOKUPVALUE, но она оперирует только конкретными значениями при поиске, к тому же не понятно как в неё добавить TOPN. Правда, я изучаю DAX всего несколько дней, поэтому чего-то могу не понимать. |
|
04.06.2012, 12:41 | #11 |
Участник
|
Коллеги,
Спасибо всем за интерес к данной теме. Огромное спасибо за помощь 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)). |
|