25.01.2005, 11:56 | #1 |
Участник
|
Join трех таблиц (две к одной)
Скорее всего этот вопрос уже поднимался на форуме, по-моему, один раз я его даже видел мельком, но второй раз не нашел. =(
Проблема в том, что я не могу соединить три таблицы. (две к одной !) аналог на SQL PHP код:
PHP код:
PHP код:
Подскажите как быть в даной ситуации и почему такое происходит?! |
|
25.01.2005, 12:11 | #2 |
NavAx
|
ДВЕ таблицы к ОДНОЙ??!!
А смысл? Вообще-то, в теории РБД, таблицы связываются последовательно. Поэтому, нужно цеплять InventTable не к IJTrans, а к InventDim: PHP код:
|
|
25.01.2005, 12:13 | #3 |
Moderator
|
PHP код:
__________________
Андрей. |
|
|
За это сообщение автора поблагодарили: mazzy (5). |
25.01.2005, 12:15 | #4 |
Moderator
|
и еще, в строчке
PHP код:
__________________
Андрей. |
|
25.01.2005, 12:39 | #5 |
Участник
|
2Dron AKA andy
Спасибо! Gопробую использовать Ваш код. P.S. 2Maximin Цитата:
ДВЕ таблицы к ОДНОЙ??!!
А смысл? Вообще-то, в теории РБД, таблицы связываются последовательно. Поэтому, нужно цеплять InventTable не к IJTrans, а к InventDim: Бывают связи и две, и три, и четыре к одной, что не противоречит теории РБД. InventTable в моем случае необходимо соединять именно с InventJournalTrans по полю ItemId. Но все равно спасибо за ответ! |
|
02.02.2005, 09:56 | #6 |
Участник
|
Цитата:
Изначально опубликовано Maximin
Вообще-то, в теории РБД, таблицы связываются последовательно. Это наверное в теории MBS так должны поступать. |
|
02.02.2005, 11:02 | #7 |
Участник
|
В теории РБД таблицы не связываются последовательно - попробуйте в Query Analyzer
поиграться и убедитесь, а вот в Аксапте похоже что это так. Что касается проблем с вашим соединением, то действительно надо писать qbds_jItems.addLink вместо qbds_jTrans.addLink и все заработает, то есть AddLink надо всегда писать именно со стороны "дочернего" датасоурса и все будет нормально, тоже касается и FetchMode и JoinMode |
|
02.02.2005, 11:32 | #8 |
Участник
|
Цитата:
Изначально опубликовано Nikolaich
В теории РБД таблицы не связываются последовательно - попробуйте в Query Analyzer поиграться и убедитесь, а вот в Аксапте похоже что это так. Можно только : 1. Либо хитро...ый способ через RecId (писать критерий выбора в поле RecId) (решение от mbs - кошмар какой-то) 2. использовать class Connection. Хотя... один фиг - с точки зрения sql-сервера всё равно курсорами всё пойдёт, так что если хотите быстродействие - пишите connection (хотя бы селект сформируется в нужном виде). |
|
02.02.2005, 11:38 | #9 |
Участник
|
Цитата:
В теории РБД таблицы не связываются последовательно - попробуйте в Query Analyzer
Я имел в виду следующий запрос, который свободно выполняется в QA PHP код:
|
|
02.02.2005, 12:11 | #10 |
Участник
|
Если за "теорию РБД" считать реляционную алгебру, то джойны действительно должны выполнятся строго последовательно. Ибо оная алгебра оперирует бинарными и унарными операторами, т.е.
t1 join t2 join t3 рассматривается как 2 последовательных операции (t1 join t2) join t3 Однако движок СУРБД никто не принуждает следовать строго логике реляционной алгебры, главное чтобы результат был правильный, а тут действительно зачастую порядок и сложность проведения операции не влияют на конечный ответ. |
|
02.02.2005, 12:15 | #11 |
Участник
|
Использовать класс Connection хорошая идея для обеспечения правильности и "кашерности" запроса, но этот метод имеет 3 существенных недостатка.
1) ResultSet вы не привяжете к DataSource на форме - то есть придется заполнять какую-то временную таблицу если хотите в интерфейсе эти данные отобразить. 2) Вы не привяжете SysQueryForm (форма запросов) к Connection а query можно - то бишь теряется удобство работы для пользователя. 3) Нужно быть предельно аккуратным при составлении запросов через Connection - не забывайте про поле DataAreaiD !!!! В QUERY это все учитывается по умолчанию на уровне системного ядра. В общем, надо пользоваться query мучаясь и не роптать |
|
02.02.2005, 12:19 | #12 |
Участник
|
Кстати помнится где то тут на форуме проскальзывала давно мессага о том что Connection порядочно тормозит при извлечении записей с сервера - в 10 раз медленее чем QueryRun или встроенный select, по каким то причинам.
|
|
02.02.2005, 12:25 | #13 |
Участник
|
Цитата:
[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 |
Участник
|
Цитата:
Изначально опубликовано Alks
Кстати помнится где то тут на форуме проскальзывала давно мессага о том что Connection порядочно тормозит при извлечении записей с сервера - в 10 раз медленее чем QueryRun или встроенный select, по каким то причинам. Просто я привык уже к мелко-мягкому... у него всё через одно место делается. Хочеться узнать обоснование и условия этого явления, а самому проверять просто лень |
|
02.02.2005, 12:32 | #15 |
Модератор
|
Внесу и мой "Фи" - мало того, что Connection - это просто дурной тон программирования в аксе, (только при самописном импорте/экспорте, возможно, стоит сделать исключение), но и при использовании C отключается возможнось проверки на взаимные блокировки. Господа из знакомой консалтинговой копмании как-то "напоролись" подобный код. Г-на программиста убить были готовы
Спасибо им, кстати, за ценный совет! P.S. А что Вы подразумеваете под "не последовательной" связкой таблиц?? паралельную? И какой тогда будет Ваш запрос? Т.е. в 2х связанных таблицах будет происходить выборка по значению в одной? Хм. Боюсь, в аксе это действительно не поддерживается. С Уважением, Георгий. |
|
02.02.2005, 12:36 | #16 |
Участник
|
Цитата:
Утверждение конечно бесспорно, но !!!
axpat-овский псевдо-sql этого не делает, т.е. указать и выполнить условие (t1 join t2) join t3 (on t1.id1 = t3.id1) НЕВОЗМОЖНО. ... Так что Microsoft sucks!!!! Т.е. действительно есть в движке переводящим аксаптовские запросы в 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 |
Участник
|
Цитата:
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 |
Участник
|
connection - конечно с точки зрения удобства, читабельности и т.п. - это конечно геморрой.
Но при большой объёме обробатываемых данных как быть? SQL - (как DML) язык управления массивами данных! ЗАчем господам понадобилось убирать все приемущества (а именно операции с наборами данных)? Почему появились конструкции типа while select? - иммено это и есть пример плохого тона программирования! Посмотрите трайс на sql-сервере ужаснётесь... оцените время выполнения сложного sql запроса с помощю AOS (для начала попробуйте его написать!) и с помощю analyser-а. (простым select-ом) Просто насколько я понимаю - это надо принять как данность и пытаться существовать в таких условиях. К сожалению.... Так что : "медведя можно научить ездить на велосипеде, но будет ли ему от этого польза и удовольствие?" |
|
02.02.2005, 12:56 | #19 |
Участник
|
Да, к сожалению это так - придется терпеть. Сам не понимаю зачем многих прелестей
SQL лишили - например, оператора Having и других, но Connection еще в большие дебри может завести. А что while select ? Он нужен для того выполнять бизнес-логику в цикле пробега по массиву данных когда не просто нужно обновить одно поле, а выполнить более сложную бизнес-логику когда одним операторм не обойдешься. Для простых случаев придумали вроде update_recordset |
|
02.02.2005, 13:09 | #20 |
Участник
|
Цитата:
Изначально опубликовано Nikolaich
Для простых случаев придумали вроде update_recordset простая операция? - элементарная! Если попробуете для этой цели update_recordset - получите приятную возможность обратиться в mbs с уведомлением о фатальной ошибке. Лично я пришёл к выводу что в "аксе" и логика, комбинаторика, бинарные операции и т.п. лишаются речи перед тривиальным перебором И это заложено в движок sql... но это совсем другая история. |
|
Теги |
ftechmode, join, query, как правильно, полезное |
|
|