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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.01.2005, 11:56   #1  
ATimTim is offline
ATimTim
Участник
 
395 / 13 (1) ++
Регистрация: 10.06.2004
Адрес: Питер
Join трех таблиц (две к одной)
Скорее всего этот вопрос уже поднимался на форуме, по-моему, один раз я его даже видел мельком, но второй раз не нашел. =(
Проблема в том, что я не могу соединить три таблицы. (две к одной !)
аналог на SQL
PHP код:
SELECT *
  
FROM InventJournalTrans 
         inner join
       InventDim 
         on InventJournalTrans
.ToInventDimId InventDim.inventDimId 
         inner join
       InventTable  
         on  InventTable
.ItemId InventJournalTrans.ItemId 
код Axapta

PHP код:
 qbds_jTrans query.addDataSource       (tablenum(InventJournalTrans)); // здесь qbds_jTrans = SELECT * FROM InventJournalTrans
qbds_Dim    qbds_jTrans.addDataSource (tablenum(InventDim)); // здесь qbds_jTrans = SELECT * FROM InventJournalTrans JOIN * FROM InventDim
qbds_jItems qbds_jTrans.addDataSource (tablenum(InventTable));  // проблемная строка, после нее сбрасывается join с предыдущей таблицей и qbds_jTrans становится равной SELECT * FROM INVENTJOURNALTRANS

qbds_jTrans.addLink  (fieldnum(InventJournalTransItemId), fieldnum(InventTableItemId));
qbds_Dim.addLink  (fieldnum(InventJournalTransToInventDimId), fieldnum(InventDim,InventDimid)); 
на строчке
PHP код:
qbds_jItems qbds_jTrans.addDataSource (tablenum(InventTable)); 
qbds_jTrans вновь становится равным SELECT * FROM InventJournalTrans
Подскажите как быть в даной ситуации и почему такое происходит?!
Старый 25.01.2005, 12:11   #2  
Maximin is offline
Maximin
NavAx
NavAx Club
 
412 / 346 (12) ++++++
Регистрация: 09.10.2002
Адрес: Москва
ДВЕ таблицы к ОДНОЙ??!!
А смысл? Вообще-то, в теории РБД, таблицы связываются последовательно.
Поэтому, нужно цеплять InventTable не к IJTrans, а к InventDim:
PHP код:
qbds_jItems qbds_Dim.addDataSource (tablenum(InventTable)); 
Ну, и линки расставить в соотетствии, ясное дело.
Старый 25.01.2005, 12:13   #3  
Dron AKA andy is offline
Dron AKA andy
Moderator
 
944 / 253 (10) ++++++
Регистрация: 27.03.2002
Адрес: Москва
PHP код:
...
qbds_Dim    qbds_jTrans.addDataSource (tablenum(InventDim));

qbds_Dim.joinMode(JoinMode::InnerJoin);
qbds_Dim.fetchMode(QueryFetchMode::One2One);

qbds_jItems qbds_jTrans.addDataSource (tablenum(InventTable)); 

qbds_jItems.joinMode(JoinMode::InnerJoin);
qbds_jItems.fetchMode(QueryFetchMode::One2One); 
__________________
Андрей.
За это сообщение автора поблагодарили: mazzy (5).
Старый 25.01.2005, 12:15   #4  
Dron AKA andy is offline
Dron AKA andy
Moderator
 
944 / 253 (10) ++++++
Регистрация: 27.03.2002
Адрес: Москва
и еще, в строчке
PHP код:
qbds_jTrans.addLink  (fieldnum(InventJournalTransItemId), fieldnum(InventTableItemId)); 
вместо qbds_jTrans, вроде бы, должен быть qbds_jItems.
__________________
Андрей.
Старый 25.01.2005, 12:39   #5  
ATimTim is offline
ATimTim
Участник
 
395 / 13 (1) ++
Регистрация: 10.06.2004
Адрес: Питер
2Dron AKA andy
Спасибо!
Gопробую использовать Ваш код.

P.S.
2Maximin
Цитата:
ДВЕ таблицы к ОДНОЙ??!!
А смысл? Вообще-то, в теории РБД, таблицы связываются последовательно.
Поэтому, нужно цеплять InventTable не к IJTrans, а к InventDim:
Не согласен.
Бывают связи и две, и три, и четыре к одной, что не противоречит теории РБД.
InventTable в моем случае необходимо соединять именно с InventJournalTrans по полю ItemId.
Но все равно спасибо за ответ!
Старый 02.02.2005, 09:56   #6  
alexbn is offline
alexbn
Участник
 
46 / 11 (1) +
Регистрация: 23.04.2004
Цитата:
Изначально опубликовано Maximin

Вообще-то, в теории РБД, таблицы связываются последовательно.
???? Вы с чего это выдумали ????
Это наверное в теории MBS так должны поступать.
Старый 02.02.2005, 11:02   #7  
Nikolaich is offline
Nikolaich
Участник
 
238 / 10 (1) +
Регистрация: 15.12.2004
В теории РБД таблицы не связываются последовательно - попробуйте в Query Analyzer
поиграться и убедитесь, а вот в Аксапте похоже что это так.
Что касается проблем с вашим соединением, то действительно надо писать

qbds_jItems.addLink вместо qbds_jTrans.addLink и все заработает, то есть
AddLink надо всегда писать именно со стороны "дочернего" датасоурса и все будет нормально, тоже касается и FetchMode и JoinMode
Старый 02.02.2005, 11:32   #8  
alexbn is offline
alexbn
Участник
 
46 / 11 (1) +
Регистрация: 23.04.2004
Цитата:
Изначально опубликовано Nikolaich
В теории РБД таблицы не связываются последовательно - попробуйте в Query Analyzer
поиграться и убедитесь, а вот в Аксапте похоже что это так.
в долбанном axapta-вском sql-е , если ,конечно, так его можно назвать, - ДЕЙСТВИТЕЛЬНО так. И никакими способами прицепить критерий (ещё одной таблицы)к родительской таблице нелзя!

Можно только :
1. Либо хитро...ый способ через RecId (писать критерий выбора в поле RecId)
(решение от mbs - кошмар какой-то)
2. использовать class Connection.


Хотя... один фиг - с точки зрения sql-сервера всё равно курсорами всё пойдёт, так что если хотите быстродействие - пишите connection (хотя бы селект сформируется в нужном виде).
Старый 02.02.2005, 11:38   #9  
ATimTim is offline
ATimTim
Участник
 
395 / 13 (1) ++
Регистрация: 10.06.2004
Адрес: Питер
Цитата:
В теории РБД таблицы не связываются последовательно - попробуйте в Query Analyzer
Наверное, мы с Вами вкладываем разный смысл в понятия "последовательно", "две таблицы к одной"
Я имел в виду следующий запрос, который свободно выполняется в QA

PHP код:
SELECT *
  
FROM InventJournalTrans 
         inner join
       InventDim 
         on InventJournalTrans
.ToInventDimId InventDim.inventDimId 
         inner join
       InventTable  
         on  InventJournalTrans
.ItemId InventTable.ItemId 
в котором две таблицы (InventDim , InventTable ) соединяются с InventJournalTrans . Это вид соединения я назвал "две к одной"
Старый 02.02.2005, 12:11   #10  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Если за "теорию РБД" считать реляционную алгебру, то джойны действительно должны выполнятся строго последовательно. Ибо оная алгебра оперирует бинарными и унарными операторами, т.е.
t1 join t2 join t3 рассматривается как 2 последовательных операции
(t1 join t2) join t3

Однако движок СУРБД никто не принуждает следовать строго логике реляционной алгебры, главное чтобы результат был правильный, а тут действительно зачастую порядок и сложность проведения операции не влияют на конечный ответ.
Старый 02.02.2005, 12:15   #11  
Nikolaich is offline
Nikolaich
Участник
 
238 / 10 (1) +
Регистрация: 15.12.2004
;)
Использовать класс Connection хорошая идея для обеспечения правильности и "кашерности" запроса, но этот метод имеет 3 существенных недостатка.

1) ResultSet вы не привяжете к DataSource на форме - то есть придется заполнять какую-то временную таблицу если хотите в интерфейсе эти данные отобразить.
2) Вы не привяжете SysQueryForm (форма запросов) к Connection а query можно - то бишь теряется удобство работы для пользователя.
3) Нужно быть предельно аккуратным при составлении запросов через Connection -
не забывайте про поле DataAreaiD !!!! В QUERY это все учитывается по умолчанию на уровне системного ядра.

В общем, надо пользоваться query мучаясь и не роптать
Старый 02.02.2005, 12:19   #12  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Кстати помнится где то тут на форуме проскальзывала давно мессага о том что Connection порядочно тормозит при извлечении записей с сервера - в 10 раз медленее чем QueryRun или встроенный select, по каким то причинам.
Старый 02.02.2005, 12:25   #13  
alexbn is offline
alexbn
Участник
 
46 / 11 (1) +
Регистрация: 23.04.2004
Цитата:
[i]t1 join t2 join t3 рассматривается как 2 последовательных операции
(t1 join t2) join t3
[/B]
Утверждение конечно бесспорно, но !!!
axpat-овский псевдо-sql этого не делает,
т.е. указать и выполнить условие (t1 join t2) join t3 (on t1.id1 = t3.id1) НЕВОЗМОЖНО.
в наборе (t1 join t2) нет t1 - работают ограничения только для t2.

Так что Microsoft sucks!!!!
Oracle forever
Старый 02.02.2005, 12:30   #14  
alexbn is offline
alexbn
Участник
 
46 / 11 (1) +
Регистрация: 23.04.2004
Цитата:
Изначально опубликовано Alks
Кстати помнится где то тут на форуме проскальзывала давно мессага о том что Connection порядочно тормозит при извлечении записей с сервера - в 10 раз медленее чем QueryRun или встроенный select, по каким то причинам.
интресно. а поподробнее можно?
Просто я привык уже к мелко-мягкому... у него всё через одно место делается.
Хочеться узнать обоснование и условия этого явления,
а самому проверять просто лень
Старый 02.02.2005, 12:32   #15  
George Nordic is offline
George Nordic
Модератор
Аватар для George Nordic
Злыдни
 
4,479 / 1250 (50) ++++++++
Регистрация: 17.12.2003
Адрес: Moscow
Записей в блоге: 9
Внесу и мой "Фи" - мало того, что Connection - это просто дурной тон программирования в аксе, (только при самописном импорте/экспорте, возможно, стоит сделать исключение), но и при использовании C отключается возможнось проверки на взаимные блокировки. Господа из знакомой консалтинговой копмании как-то "напоролись" подобный код. Г-на программиста убить были готовы

Спасибо им, кстати, за ценный совет!

P.S. А что Вы подразумеваете под "не последовательной" связкой таблиц?? паралельную? И какой тогда будет Ваш запрос?
Т.е. в 2х связанных таблицах будет происходить выборка по значению в одной?
Хм. Боюсь, в аксе это действительно не поддерживается.

С Уважением,
Георгий.
Старый 02.02.2005, 12:36   #16  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Цитата:
Утверждение конечно бесспорно, но !!!
axpat-овский псевдо-sql этого не делает,
т.е. указать и выполнить условие (t1 join t2) join t3 (on t1.id1 = t3.id1) НЕВОЗМОЖНО.
...
Так что Microsoft sucks!!!!
Делает. То о чём вы хотите сказать справедливо только для outer join.
Т.е. действительно есть в движке переводящим аксаптовские запросы в SQL глюк связанный с outer join:
(t1 join t2) join t3 (on t1.id1 = t3.id1) - работает
(t1 join t2) outer join t3 (on t1.id1 = t3.id1) - выдаёт ошибку со смыслом "не могу понять как джойнить t3 с t2.
Еще раз повторяю - для outer join-ов.
Действительно sucks,.... но сколько раз я раздражённо морщусь когда тут ругают MS. Всё таки Axapta - детище Damgaard, несмотря на то что последняя была куплена by Navision, а последняя была куплена by MS.
Старый 02.02.2005, 12:41   #17  
Alks is offline
Alks
Участник
 
336 / 41 (2) +++
Регистрация: 23.07.2004
Адрес: г. Новокузнецк
Цитата:
P.S. А что Вы подразумеваете под "не последовательной" связкой таблиц?? паралельную? И какой тогда будет Ваш запрос?
На самом деле он написал какой будет запрос:
(t1 join t2) join t3 (on t1.id1 = t3.id1)

Это нормально, т.к. таблица t3 по идеологии РБД джойнится с РЕЗУЛЬТАТОМ t1 join t2, а в этом результате есть и колонки из t1 и колонки из t2, поэтому в join ... on ... вполне корректно употреблять t3.fld == t1.fld, как бы минуя таблицу t2. Это правильно. Непонятно почему в аксапте outer join этого не поддерживает.
Старый 02.02.2005, 12:46   #18  
alexbn is offline
alexbn
Участник
 
46 / 11 (1) +
Регистрация: 23.04.2004
connection - конечно с точки зрения удобства, читабельности и т.п. - это конечно геморрой.
Но при большой объёме обробатываемых данных как быть?

SQL - (как DML) язык управления массивами данных! ЗАчем господам понадобилось убирать все приемущества (а именно операции с наборами данных)?
Почему появились конструкции типа while select?
- иммено это и есть пример плохого тона программирования!
Посмотрите трайс на sql-сервере ужаснётесь... оцените время выполнения сложного sql запроса с помощю AOS (для начала попробуйте его написать!) и с помощю analyser-а. (простым select-ом)

Просто насколько я понимаю - это надо принять как данность и пытаться существовать в таких условиях. К сожалению....

Так что : "медведя можно научить ездить на велосипеде, но будет ли ему от этого польза и удовольствие?"
Старый 02.02.2005, 12:56   #19  
Nikolaich is offline
Nikolaich
Участник
 
238 / 10 (1) +
Регистрация: 15.12.2004
Да, к сожалению это так - придется терпеть. Сам не понимаю зачем многих прелестей
SQL лишили - например, оператора Having и других, но Connection еще в большие дебри может завести.
А что while select ? Он нужен для того выполнять бизнес-логику в цикле пробега по массиву данных когда не просто нужно обновить одно поле, а выполнить более сложную бизнес-логику когда одним операторм не обойдешься.
Для простых случаев придумали вроде update_recordset
Старый 02.02.2005, 13:09   #20  
alexbn is offline
alexbn
Участник
 
46 / 11 (1) +
Регистрация: 23.04.2004
Цитата:
Изначально опубликовано Nikolaich
Для простых случаев придумали вроде update_recordset
А если обновить поля одной таблицы по значениям из второй?
простая операция? - элементарная!
Если попробуете для этой цели update_recordset - получите приятную возможность обратиться в mbs с уведомлением о фатальной ошибке.

Лично я пришёл к выводу что в "аксе" и логика, комбинаторика, бинарные операции и т.п. лишаются речи перед тривиальным перебором
И это заложено в движок sql... но это совсем другая история.
Теги
ftechmode, join, query, как правильно, полезное

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Порядок выполнения GroupBy и Exists Join для временных таблиц S.Kuskov DAX: Программирование 6 06.12.2012 16:55
Как сдлеать join по одной таблице, а курсор по другой cerbo DAX: Программирование 9 03.10.2008 09:29
Данные в Grid из таблиц, связанных по Outer Join cherv DAX: Программирование 2 17.02.2007 01:36
Глюки в Query с разными типами Join (в т.ч. NonExistsJoin) к одной таблице gl00mie DAX: Программирование 10 14.02.2007 13:22
outer join для трех таблиц r25 DAX: Программирование 4 29.04.2004 15:42
Опции темы Поиск в этой теме
Поиск в этой теме:

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

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

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

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