AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск Все разделы прочитаны

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.02.2005, 15:32   #1  
Ronin is offline
Ronin
aka awas
NavAx Club
 
16 / 30 (2) +++
Регистрация: 21.06.2004
Адрес: г. Москва
? 2 и более OUTER JOIN к одному паренту
Доброго времени суток, вам, господа и дамы!

Не подскажите, как построить селект с 2мя и более outer join'ами с одним парентом? Или объяснить мне в чем я не прав.

У меня на последнем Join'e ругается что

"Невозможно выбрать запись в 'Условия оплаты' ('PaymTerm')
Использован оператор объединения таблиц join, но выражение WHERE не содержит связи между таблицами."

static void Job10(Args _args)
{
SalesTable contractTable;
EmplTable emplTable;
PaymTerm paymTerm;
;

while
select SalesName
from contractTable

outer join NumOfDays, Description
from paymTerm
where paymTerm.PaymTermId == contractTable.Payment

outer join Name
from emplTable
where emplTable.EmplId == contractTable.SalesResponsible

{
info(strfmt("%1 %2", paymTerm.NumOfDays, contractTable.SalesName));
}

}

Хинт: с "обыкновенными", inner join'ами, все job запускается...
Старый 25.02.2005, 15:37   #2  
db is offline
db
Роман Долгополов (RDOL)
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
 
393 / 692 (24) +++++++
Регистрация: 01.04.2004
Адрес: Москва
Это глюк ядра, а точнее парсера запросов. В сервисную систему регистрировал, когда исправят не знаю.
хинт: если не хотите ждать, то используйте в качестве СУБД Oracle - парсер запросов для него отрабатывает корректно
Старый 25.02.2005, 20:32   #3  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Изначально опубликовано db
хинт: если не хотите ждать, то используйте...
Или query. см.руководство разработчика. ключевое слово "Sequencing of retrieved records"
Старый 28.02.2005, 10:11   #4  
Ronin is offline
Ronin
aka awas
NavAx Club
 
16 / 30 (2) +++
Регистрация: 21.06.2004
Адрес: г. Москва
Спасибо всем за ответ!

db: на счет Oracle - узнать это было интересно, особенно в конетксте наличия подводных камней при переносе базы с одной платформы на другую.

Mazzy: с помощью query задача и решилась, причем еще до написания поста. Просто этот случай своей нелепостью вызывал уже чисто академический интерес: как можно в конструкции select сделать более 1го outer join, и если нельзя, то почему.

Ответы я похоже получил исчерпывающие.
Спасибо.
:-)
Старый 28.02.2005, 11:28   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
awas, в ФАК этот ответ заносить стоит?
Старый 28.02.2005, 15:47   #6  
Ronin is offline
Ronin
aka awas
NavAx Club
 
16 / 30 (2) +++
Регистрация: 21.06.2004
Адрес: г. Москва
ИМХО: однозначно.
Старый 28.02.2005, 17:50   #8  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Цитата:
Или query
Вот это я не понял...
PHP код:
static void Job40(Args _args)
{
    
Query       q = new Query();
    
QueryRun    qr;
    
QueryBuildDataSource qbDS1qbDS2;
    ;

    
qbDS1 q.addDataSource(tableNum(InventSum));

    
qbDS2 qbDS1.addDataSource(tableNum(InventTable));
    
qbDS2.joinMode(JoinMode::OuterJoin);
    
qbDS2.fetchMode(QueryFetchMode::One2One);
    
qbDS2.relations(true);

    
qbDS2 qbDS1.addDataSource(tableNum(InventDim));
    
qbDS2.joinMode(JoinMode::OuterJoin);
    
qbDS2.fetchMode(QueryFetchMode::One2One);
    
qbDS2.relations(true);

    
info(qbDS1.toString());

    
qr = new QueryRun(q);
    
qr.next();

Невозможно выбрать запись в 'Складская аналитика' ('InventDim')
Использован оператор объединения таблиц join, но выражение WHERE не содержит связи между таблицами.
Старый 28.02.2005, 19:37   #9  
Ronin is offline
Ronin
aka awas
NavAx Club
 
16 / 30 (2) +++
Регистрация: 21.06.2004
Адрес: г. Москва
Еще в копилку.

Немного интересного обнаружил при анализе одного запроса с помощью профайлера.
Запрос имеет примерно следующую структуру:

select Table_1
inner join Table_2
outer join Table_2_1
outer join Table _2_1_1
outer join Table_2_2
outer join Table_2_2_1

Аксапта этот запрос разбила на 3...

Этот выполнялся соответственно 1 раз
select Table_1
join Table_2


Эти части выполнялись соответственно столько раз, сколько записей вернулось при 1 запросе...

select Table_2_1
outer join Table _2_1_1

select join Table_2_2
outer join Table_2_2_1

При этом на n-ой записи метод queryRun.next() выдает ошибку типа:
"Невозможно выбрать запись в 'Table_2_2_1' ('Table_2_2_1')
Из базы данных выбрано нулевое значение (NULL), которое не поддерживается."
Старый 20.07.2005, 17:16   #10  
Sanya is offline
Sanya
Участник
 
172 / 11 (1) +
Регистрация: 24.04.2003
Адрес: Киев
С помощью query задача решается не корректно.
Пример запроса:
Таблица 1
outer joun Таблица 2
outer joun Таблица 3

В таблице 1 - 1-а запись
В таблице 2 - 0 - записей
В таблице 3 - 1-а запись связанная с таблицей 1
Цикл по такому запросу сделает 2 итерации:
на 1-ой: Таблица 1 инициализирована
Таблица 2 не инициализирована(оно и понятно в ней нет записей)
Таблица 3 не инициализирована(!!!)

на 2-ой: Таблица 1 инициализирована
Таблица 2 не инициализирована(оно и понятно в ней нет записей)
Таблица 3 инициализирована
Проект в приатацином файле.

Пока только один вариант решения, разбивать запрос на 2.
Вложения
Тип файла: xpo test.xpo (17.9 Кб, 613 просмотров)
Старый 25.07.2005, 18:09   #11  
vallys is offline
vallys
Developer
 
146 / 108 (0) +++++
Регистрация: 18.01.2005
Lightbulb Есть предложение
Строить такие запросы (2 и более OUTER JOIN к одному паренту) на Х++ для таблиц со свойством "SaveDataPerCompany" == "Yes" можно путем добавления фиктивной связи между дочерними таблицами по полю DataAreaId:

PHP код:
ChildTable2.DataAreaId == ChildTable1.DataAreaId || ChildTable2.DataAreaId != ChildTable1.DataAreaId 
Например, запрос из первого сообщения примет вид:

PHP код:
while
select SalesName
from contractTable

outer join NumOfDays
Description
from paymTerm
where paymTerm
.PaymTermId == contractTable.Payment

outer join Name
from emplTable
where 
(emplTable.DataAreaId == paymTerm.DataAreaId || emplTable.DataAreaId != paymTerm.DataAreaId) &&
emplTable.EmplId == contractTable.SalesResponsible 
Это, естественно, добавит работы парсеру SQL-сервера, но т.к. поле DataAreaId входит во все индексы таблиц со свойством "SaveDataPerCompany" == "Yes", то никаких побочных эффектов (кроме пренебрежимо малого падения скорости) быть не должно.

Аналогично для Query, если у вложенных датасоурсов свойство "FetchMode" == "1:1".
За это сообщение автора поблагодарили: bagyr (1), alex55 (1), S.Kuskov (4).
Старый 25.07.2005, 20:16   #12  
Logger is offline
Logger
Участник
Лучший по профессии 2015
Лучший по профессии 2014
 
3,952 / 3230 (115) ++++++++++
Регистрация: 12.10.2004
Адрес: Москва
Записей в блоге: 2
Цитата:
Вот это я не понял...
Wamr, я недавно тоже столкнулся с подобным поведением автоджоина. Причем глючило только в случае если на InventDim не было ни одного Range. Стоило добавить хоть один range как все работало хорошо.

Я решил эту проблему
qbDS2.relations(false);
qbDS2.addLink(fieldNum(InventSum, InventDimId), fieldNum(InventDim, InventDimId))

т.е. явным прописыванием связи между таблицами...
Старый 18.12.2005, 19:22   #13  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от vallys
Аналогично для Query, если у вложенных датасоурсов свойство "FetchMode" == "1:1".
vallys здорово придумано с select, но вот "аналогично для Query" я не понимаю как составить связь. Всяко вертел пример Wamr, но что то он у меня так и не заработал. Не могли бы приставить необходимые строчки?
Старый 18.12.2005, 19:36   #14  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от Logger
Wamr, я недавно тоже столкнулся с подобным поведением автоджоина. Причем глючило только в случае если на InventDim не было ни одного Range. Стоило добавить хоть один range как все работало хорошо.

Я решил эту проблему
qbDS2.relations(false);
qbDS2.addLink(fieldNum(InventSum, InventDimId), fieldNum(InventDim, InventDimId))

т.е. явным прописыванием связи между таблицами...
Переписывал пример с учетом замечаний Logger, но исходная ошибка не исчезает.

И к awas вопрос - как ему совет mazzy помог? Я тоже посмотрел те картинки, но решения проблемы оттуда не увидел. Может у вас просто query на автомате создался со свойстовом "FetchMode" == "1:n" на датасорсе и дело двинулось по другому пути? но исходная проблема не решилась?
Старый 18.12.2005, 20:09   #15  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Попробуйте так
X++:
    qbDS2.relations(false);                
    qbDS2.addRange(fieldNum(InventDim, InventDimId)).
        value(strfmt("(((%2.dataAreaId == %3.DataAreaId) || (%2.dataAreaId != %3.DataAreaId)) && " +
                     "(%1.inventDimId == %3.inventDimId))",
                        qbDS1.name(), 
                        q.dataSourceTable(tableNum(InventTable)).name(), 
                        qbDS2.name()));
__________________
Axapta v.3.0 sp5 kr2
Старый 19.12.2005, 07:38   #16  
Perc is offline
Perc
Участник
 
194 / 57 (2) ++++
Регистрация: 05.03.2005
Цитата:
Сообщение от AndyD
Попробуйте так
X++:
    qbDS2.relations(false);                
    qbDS2.addRange(fieldNum(InventDim, InventDimId)).
        value(strfmt("(((%2.dataAreaId == %3.DataAreaId) || (%2.dataAreaId != %3.DataAreaId)) && " +
                     "(%1.inventDimId == %3.inventDimId))",
                        qbDS1.name(), 
                        q.dataSourceTable(tableNum(InventTable)).name(), 
                        qbDS2.name()));
Спсб AndyD. Наставил на путь истинный. Я делал почти тоже самое, но наивно решил не заморачиваться с strfmt() в тесте своем и вбивал сразу же условие текстом
X++:
    qbDS2.addRange(fieldNum(InventDim, InventDimId)).
        value("(((InventTable.dataAreaId == InventDim.DataAreaId) || (InventTable.dataAreaId != InventDim.DataAreaId)) && (InventSum.inventDimId == InventDim.inventDimId))");
вот это меня и подвело. Ни разу даже мысли не возникло проверить что за текст там получается и как на самом деле датасорсы называются.
Не ошибайтесь так люди
Старый 19.12.2005, 08:16   #17  
AndyD is offline
AndyD
Участник
КОРУС Консалтинг
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
 
2,560 / 2479 (88) +++++++++
Регистрация: 20.08.2005
Можно было явно дать название датасоурсам

qbDS1 = q.addDataSource(tableNum(InventSum), "InventSum");
или qbDS1.Name("InventSum");
и т.д.
Тогда бы ваш вариант работал.
__________________
Axapta v.3.0 sp5 kr2

Последний раз редактировалось AndyD; 19.12.2005 в 09:08.
Старый 19.12.2005, 10:27   #18  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
Хочу отметить, что Job40 (см. тут ) замечательно работает на Oracle и никак не работает на MS SQL.
Старый 19.12.2005, 13:21   #19  
vallys is offline
vallys
Developer
 
146 / 108 (0) +++++
Регистрация: 18.01.2005
Цитата:
Сообщение от Wamr
Хочу отметить, что Job40 (см. тут ) замечательно работает на Oracle и никак не работает на MS SQL.
Если перед info добавить
Код:
qbDS2.addRange(fieldnum(InventDim, DataAreaId)).value(strfmt(
        "((%1.DataAreaId == %2.DataAreaId) || (%1.DataAreaId != %2.DataAreaId))",
        qbDS2.name(),
        q.dataSourceTable(tablenum(InventTable)).name()
        ));
то и на MS SQL заработает
Старый 19.12.2005, 13:29   #20  
Wamr is offline
Wamr
----------------
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
 
1,737 / 858 (32) +++++++
Регистрация: 15.01.2002
Адрес: Москва
Записей в блоге: 7
а включаешь
PHP код:
    qbDS2 qbDS1.addDataSource(tableNum(InventDim));
    
qbDS2.joinMode(JoinMode::OuterJoin);
    
qbDS2.fetchMode(QueryFetchMode::One2One);
    
qbDS2.relations(true);
//    qbDS2.addLink(fieldNum(InventSum, InventDimId), fieldNum(InventDim, InventDimId));
    
qbDS2.addRange(fieldnum(InventDimDataAreaId)).value(strfmt(
        
"((%1.DataAreaId == %2.DataAreaId) || (%1.DataAreaId != %2.DataAreaId))",
        
qbDS2.name(),
        
q.dataSourceTable(tablenum(InventTable)).name()
        )); 
- не работает
Наверно, это из-за SaveDataPerCompany = NO

Последний раз редактировалось Wamr; 19.12.2005 в 13:36.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Двойной Outer Join в Query LTA DAX: Программирование 2 21.01.2020 09:28
Несколько outer join в запросе _scorp_ DAX: Программирование 2 11.04.2008 10:56
Данные в Grid из таблиц, связанных по Outer Join cherv DAX: Программирование 2 17.02.2007 01:36
Outer Join Anais DAX: Программирование 3 20.05.2005 12:10
outer join для трех таблиц r25 DAX: Программирование 4 29.04.2004 15:42
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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