10.07.2009, 12:45 | #1 |
Участник
|
Выборка нескольких записей из подчиненной таблицы с группировкой AND.
Есть таблица сталей
MaterialSteel SteelId и стандартов MaterialStandard StandardId StandardGroupId Есть таблица наборов этих сталей и стандартов, которая прикрепляется к InventTable и TmkSpecTable: MaterialCollection CollectionId Type RefKey RefTable MaterialCollection Relations: MaterialCollection.CollectionId == MaterialSteel.SteelId MaterialCollection.Type == 1 MaterialCollection.CollectionId == MaterialStandard.StandardId MaterialCollection.Type == 2 InventTable.ItemId == MaterialCollection.RefKey InventTable.TableId == MaterialCollection.RefTableId TmkSpecTable.SpecId == MaterialCollection.RefKey TmkSpecTable.TableId == MaterialCollection.RefTableId Пользователь может ввести набор из сталей и стандартов, по которым необходимо сделать выборку из InventTable. Необходимо выбрать только те, в которых присутствуют все стали и стандарты, выбранные пользователем. К InventTable добавил MaterialCollection, сгруппировал результат по ItemId. Выбираю из MаterialCollection.CollectionId по ИЛИ, при этом если добавлять тип коллекции, то результат пустой, равно как и если поставить "&&" в 74 строке. С представленным ниже кодом возвращаются все InventTable-s, в которых присутствуют хотя бы одна из сталей/сандартов. X++: 01 void setCollectionRange(TmkSteelText _steelText, TmkStandardText _standardText) 02 { 03 QueryBuildDataSource ds = inventTable_DS.query().dataSourceTable(tablenum(InventTable)); 04 FreeTxt rangeText; 05 int i; 06 FreeTxt parseRange(FreeTxt _txt) 07 { 08 Array arrayValues; 09 FreeTxt result; 10 TmkCollectionId collectionId; 11 boolean isFirst = true; 12 ; 13 arrayValues = TmkStringTools::explode(_txt, #COLLECTION_SEPARATOR); 14 if(arrayValues.lastIndex() > 0) 15 { 16 if(arrayValues.lastIndex() == 1) 17 { 18 collectionId = TmkStringTools::trim(arrayValues.value(1)); 19 return strfmt('(%1.%2 == "%3")', 20 inventTable_DS.query().dataSourceTable(tableNum(MaterialCollection)).name(), 21 fieldstr(MaterialCollection, CollectionId), collectionId); 22 } 23 else 24 { 25 for(i = 1; i <= arrayValues.lastIndex(); i++) 26 { 27 collectionId = TmkStringTools::trim(arrayValues.value(i)); 28 if (isFirst) 29 { 30 result = strfmt('((%1.%2 == "%3")', 31 inventTable_DS.query().dataSourceTable(tableNum(MaterialCollection)).name(), 32 fieldstr(TmkCollection, CollectionId), collectionId); 33 isFirst = false; 34 } 35 else 36 { 37 result += strfmt(' || (%1.%2 == "%3")', 38 inventTable_DS.query().dataSourceTable(tableNum(MaterialCollection)).name(), 39 fieldstr(MaterialCollection, CollectionId), collectionId); 40 } 41 } 42 } 43 } 44 result += ')'; 45 return result; 46 } 47 ; 48 if(collectionRange != null) 49 { 50 if(_standardText == '' && _steelText == '') 51 { 52 collection_ds.enabled(false); 53 collectionRange = null; 54 return; 55 } 56 } 57 else 58 { 59 if(_standardText == '' && _steelText == '') 60 return; 61 if(!collection_ds) 62 { 63 collection_ds = ds.addDataSource(tablenum(MaterialCollection)); 64 collection_ds.joinMode(JoinMode::InnerJoin); 65 collection_ds.relations(true); 66 ds.addSortField(fieldnum(inventTable, ItemId)); 67 ds.orderMode(OrderMode::GroupBy); 68 } 69 collection_ds.enabled(true); 70 collectionRange = SysQuery::findOrCreateRange(collection_ds, fieldnum(MaterialCollection, CollectionId)); 71 } 72 if(_steelText != '' && _standardText != '' ) 73 { 74 rangeText = strfmt("(%1 && %2)", parseRange(_steelText), parseRange(_standardText)); 75 } 76 else 77 { 78 if(_standardText == '') 79 rangeText = parseRange(_steelText); 80 else 81 rangeText = parseRange(_standardText); 82 } 83 collectionRange.value(rangeText); 84} AX 4.0.2163.0 SP2 Localization version: Eastern Europe |
|
10.07.2009, 13:31 | #2 |
Участник
|
По-моему, вам надо не Inner, а Exist Join использовать (без группировки).
Либо, по всем полям в InventTable надо будет так же включить группировку
__________________
Axapta v.3.0 sp5 kr2 |
|
10.07.2009, 14:28 | #3 |
Участник
|
С ExistJoin и без группировки не работает.
Включил группировку по нескольким полям InventTable - тот же результат. А можно ли привязать несколько раз MaterialCollection, каждый раз указывая необходимый CollectionId и тип, черезе InnerJoin? |
|
10.07.2009, 16:13 | #4 |
Участник
|
Можно посмотреть на генерируемый текст запроса
X++: info(query().dataSourceNo(1).toString()) |
|
10.07.2009, 16:18 | #5 |
Участник
|
SELECT * FROM InventTable
GROUP BY InventTable.RecId ASC, InventTable.ItemId ASC, InventTable.ItemName ASC, InventTable.Intracode ASC, InventTable.DiameterId ASC, InventTable.WallThicknessId ASC WHERE ((Dimension[5] = N'S0')) AND ((ChainType = 1)) AND ((PipeUnitId = N'mm')) JOIN * FROM MaterialCollection WHERE InventTable.ItemId = MaterialCollection.RefKey AND InventTable.TableId = MaterialCollection.RefTableId AND (((((MaterialCollection_1.CollectionId == "08X22H6T") || (MaterialCollection_1.CollectionId == "10G2FB")) || (MaterialCollection_1.CollectionId == "API 5L")))) |
|
14.07.2009, 11:33 | #6 |
Участник
|
поробуйте поменять порядок датасорсов в запросе
__________________
aLL woRk aNd nO JoY MAKes jAck a dULL Boy |
|