14.10.2009, 10:08 | #21 |
Участник
|
А кто-нибудь встречал в стандарте запросы с group by без использования аггрегирующих функций? (не только для временных таблиц, но и для обычных)
Я лично не сталкивался, и всегда думал, что если используешь group by, то добавь хотя бы count(RecId)... |
|
14.10.2009, 10:19 | #22 |
Ищущий знания...
|
Цитата:
и я при group by никогда не использую аггрегирующие функции, так как group by сам по себе предполагает вывод только тех полей, которые указаны в нем.
__________________
"Страх перед возможностью ошибки не должен отвращать нас от поисков истины." (с) С Уважением, Елизаров Артем |
|
|
За это сообщение автора поблагодарили: Bishop (1). |
14.10.2009, 10:28 | #23 |
Участник
|
В связи с отсутствием distinct, использование group by без аггрегирующих функций не такая уж и редкость в Axapta
|
|
14.10.2009, 12:50 | #24 |
Участник
|
Цитата:
Сообщение от lev
Ну вообще много где так делается (пример SalesFromLetter::CheckParmTable(), SalesFormLetter_PackingSlip.writeJournalSalesLink() и т.д.)
и я при group by никогда не использую аггрегирующие функции, так как group by сам по себе предполагает вывод только тех полей, которые указаны в нем. X++: while select salesParmT group by CustAccount where salesParmT.ParmId == parmId { numOfAccounts += 1; } |
|
14.10.2009, 12:54 | #25 |
Участник
|
|
|
14.10.2009, 13:16 | #26 |
Administrator
|
Ну.. не боги горшки обжигают... даже у буржуев. С одной стороны. А с другой стороны - альтернатива данному коду - есть только через exists join со справочником, что требует дополнительного мыслительного процесса - что за справочник и как он связан.
__________________
Возможно сделать все. Вопрос времени |
|
14.10.2009, 13:40 | #27 |
MCITP
|
Цитата:
либо то что тут, либо как сказали выше (и на ссылке выше тоже есть пример), делать экзист со справочником... Тоже не шибко всё красиво...
__________________
Zhirenkov Vitaly |
|
15.10.2009, 12:40 | #28 |
Участник
|
Цитата:
Для достижения distinct я пользуюсь двумя глобальными статическими методами: 1) notexists join на эту же таблицу - позволяет получить кол-во различных значений по группе полей, так же работает со временными таблицами, неприменим для таблиц с большим количеством строк (если не использовать доп. критерии), так как запрос вызывает на sql-сервере сущий ад... X++: // Возвращает кол-во различных значений заданного набора полей таблицы // Формируется запрос: #if.never select count(RecId) from table where table.FieldRange1 == value1 && // доп. условия ... notexists join tableNE // tableNE.TableId = table.TableId where tableNE.RecId < table.RecId && // основная идея tableNE.Field1 == table.Field1 && // набор полей ... && tableNE.FieldRange1 == value1 && // доп. условия ... #endif static counter distinctValues( TableId _tableId, // код таблицы container _conFields, // перечень полей container _conRanges = connull(),// перечень критериев [fieldId, range, ...] Common _tmpCommon = null // временная таблица ) { DictTable dictTable; Common common; Common commonNE; Query query; QueryBuildDataSource qbds, qbdsNE; QueryRun queryRun; int i; ; query = new Query(); qbds = query.addDataSource(_tableId, "ds1"); qbds.orderMode(OrderMode::GroupBy); qbds.addSelectionField(fieldNum(Common, RecId), SelectionField::Count); for (i = 1; i <= conlen(_conRanges) div 2; i+=2) { qbds.addRange(conpeek(_conRanges, i)).value(conpeek(_conRanges, i+1)); } qbdsNE = qbds.addDataSource(_tableId, "ds2"); qbdsNE.joinMode(JoinMode::NoExistsJoin); qbdsNE.addRange(fieldNum(Common, RecId)).value("((ds2.RecId < ds1.RecId))"); for (i = 1; i <= conlen(_conFields); i++) { qbdsNE.addLink(conpeek(_conFields, i), conpeek(_conFields, i)); } for (i = 1; i <= conlen(_conRanges) div 2; i+=2) { qbdsNE.addRange(conpeek(_conRanges, i)).value(conpeek(_conRanges, i+1)); } queryRun = new QueryRun(query); if (_tmpCommon) { dictTable = new DictTable(_tableId); common = dictTable.makeRecord(); commonNE = dictTable.makeRecord(); common.setTmpData(_tmpCommon); commonNE.setTmpData(_tmpCommon); queryRun.setCursor(common, 1); queryRun.setCursor(commonNE, 2); } queryRun.next(); return queryRun.getNo(1).RecId; } X++: // Возвращает кол-во различных значений заданного поля таблицы /* Выполняется sql-запрос: SELECT COUNT (DISTINCT Field) FROM Table WHERE ... */ server static counter distinctValuesDirect( TableId _tableId, // код таблицы FieldId _fieldId, // код поля container _conRanges = connull() // перечень критериев [fieldId, range, ...] ) { DictTable dictTable = new DictTable(_tableId); ResultSet resultSet; SqlSystem sqlSystem = new SqlSystem(); str sql; str rangeList; int i; ; if (dictTable.dataPrCompany()) { rangeList = strfmt(" where %1 = %2", dictTable.fieldName(fieldNum(Common, DataAreaId), DbBackend::Sql), sqlSystem.sqlLiteral(curext()) ); } for (i = 1; i <= conlen(_conRanges) div 2; i+=2) { rangeList = (rangeList ? "" : " where ") + rangeList + (rangeList ? " and " : "") + strfmt("%1 = %2", dictTable.fieldName(conpeek(_conRanges, i), DbBackend::Sql), sqlSystem.sqlLiteral(conpeek(_conRanges, i+1)) ); } sql = strfmt("select count (distinct %1) from %2%3", dictTable.fieldName(_fieldId, DbBackend::Sql), dictTable.name(DbBackend::Sql), rangeList); new SqlStatementExecutePermission(sql).assert(); resultSet = new Connection().createStatement().executeQuery(sql); CodeAccessPermission::revertAssert(); if (resultSet.next()) { return resultSet.getInt64(1); } return 0; } |
|
|
За это сообщение автора поблагодарили: sukhanchik (1), S.Kuskov (1). |
15.10.2009, 12:58 | #29 |
Administrator
|
Ну мне кажется что select просто с group by как бы несколько проще....
__________________
Возможно сделать все. Вопрос времени |
|
26.10.2009, 15:49 | #30 |
Участник
|
Цитата:
Сообщение от S.Kuskov
AX 4.0 SP2
Тестируя отчёт, случайно поймал глюк: X++: static void job(Args _args) { tmpTable tmpTable; counter cnt; ; tmpTable.clear(); tmpTable.Field1 = '1'; tmpTable.insert(); tmpTable.clear(); tmpTable.Field1 = '1'; tmpTable.insert(); // вставляем две одинаковые строки cnt = 0; while select tmpTable group by Field1 // where tmpTable.Field1 == '1' { cnt++; } info(int2str(cnt)); } P.S.: Обязательные условия: таблица - временная; поле - текстовое |
|
14.07.2011, 20:37 | #31 |
NavAx
|
На 2009 RU6 починили... RU5 не пробовал...
__________________
Жизнь прекрасна! Если, конечно, правильно подобрать антидепрессанты... |
|
16.01.2015, 10:25 | #32 |
Участник
|
А как вы проверяли?
Я на AX2009 RU7 сейчас опять наступил на эти грабли. Проверил на AX2012R3 - грабли все ещё там! Вот видоизменил тестовый джоб, чтобы не нужно было создавать таблицу вручную (используется таблица существующую в стандартном приложении ). X++: static void Job_test20150116(Args _args) { TmpABC TmpABC; counter cnt; ; TmpABC.clear(); TmpABC.ItemId = '1'; TmpABC.RefRecId = 0; TmpABC.doinsert(); TmpABC.clear(); TmpABC.ItemId = '1'; TmpABC.RefRecId = 1; TmpABC.doinsert(); // вставляем две одинаковые строки cnt = 0; while select TmpABC group by ItemId where TmpABC.ItemId == '1' // !!! с этим условием группировка не выполняется { info(TmpABC.ItemId); cnt++; } info(strfmt("Количество итераций цикла: %1", cnt)); } |
|
Теги |
bug, баг, временная таблица, запрос (query), ошибка |
|
Похожие темы | ||||
Тема | Ответов | |||
Временная таблица | 21 | |||
производительность: map или временная таблица | 5 | |||
Временная таблица + RLS | 6 | |||
select sum(amount) from временная таблица | 6 | |||
next и временная таблица | 3 |
|