|
14.10.2009, 12:50 | #1 |
Участник
|
Цитата:
Сообщение от 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 | #2 |
Участник
|
|
|
15.10.2009, 12:40 | #3 |
Участник
|
Цитата:
Для достижения 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 | #4 |
Administrator
|
Ну мне кажется что select просто с group by как бы несколько проще....
__________________
Возможно сделать все. Вопрос времени |
|
14.10.2009, 13:16 | #5 |
Administrator
|
Ну.. не боги горшки обжигают... даже у буржуев. С одной стороны. А с другой стороны - альтернатива данному коду - есть только через exists join со справочником, что требует дополнительного мыслительного процесса - что за справочник и как он связан.
__________________
Возможно сделать все. Вопрос времени |
|
14.10.2009, 13:40 | #6 |
MCITP
|
Цитата:
либо то что тут, либо как сказали выше (и на ссылке выше тоже есть пример), делать экзист со справочником... Тоже не шибко всё красиво...
__________________
Zhirenkov Vitaly |
|
Теги |
bug, баг, временная таблица, запрос (query), ошибка |
|
Похожие темы | ||||
Тема | Ответов | |||
Временная таблица | 21 | |||
производительность: map или временная таблица | 5 | |||
Временная таблица + RLS | 6 | |||
select sum(amount) from временная таблица | 6 | |||
next и временная таблица | 3 |
|