|
|
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Я так понимаю что SQL Access не поддерживает полное внешнее объединение, а мне надо объединить две таблицы так, чтобы все записи из обеих таблиц были отобраны(типа LEFT JOIN и RIGHT JOIN одновременно). Подскажите, как грамотнее это сэмулировать??? а то пока мне в голову только всякие доп. запросы лезут в голову, может что поэлегантнее есть (через самообъединение попробовать)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 13:16 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Я делал через третью таблицу. Напр, есть таблица "Номенклатура" с всеми кодами товара, делаешь LEFT JOIN к таблице "Расход" по коду товара и LEFT JOIN к таблице "Приход" тоже по коду товара. Таблицы "Расход" и "Приход" оказываются связанными двухсторонним объединением. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 13:23 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
предположу но не ручаюсь ... а проверять не на чем ... select * from T1 , T2 where T1.id = T2.id or T1.id is null or T1.id not in (select id from T2) or T2.id is null or T2.id not in (select id from T1) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 14:59 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Ок, интересно, ща проверим (до этих "not in (select..." я бы сам наверное не допер) :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 15:07 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
2АлексейК: неаа, не подходит такой вариант. Он знаешь че делает: на каждую запись из T1 ставит все записи из T2. Будем искать дальше... ща попробую переделать твой вариант... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 17:13 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
1. чтоб работало как предложил <АлексейК> нужно дополнить таблицы (обе) пустой записью (юнионы). Но потом еще и убрать полностью пустую из результирующего набора. 2. Вар-нт zz сводится к пристыковке справа и слева к юниону из ключей (точнее -полей связи) обеих. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 17:48 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
2assa: Пустую говоришь, ща посмотрим.... на счет варианта zz, тут я неочень допираю пока, union это конечно замечательно, но тогда по его совету, мне сначала надо получить таблицу со всеми уник. Id из T1 и T2, так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 17:55 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Ну примерно так: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 17:57 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
2 TRoUbLEs забыл я как себя ведет в MDB union и union all ... с появлением дубликатов проблем не будет? а имеющиеся дубликаты не удалятся? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 18:05 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Да, с union я думаю самый реальный вариант, потому как через WHERE с доп. SELECT(да и без него тоже) получается совершенно не то. При обработке запросов на объединение где указаны 2 таблицы, я так понимаю Access, делает следующее: он берет первую запись из T1 и начинает пробегать по всем записям из T2 отбирая их по условию в WHERE. Если мы в WHERE пишем T1.id=T2.id, тогда все OK, отбираются только совпавшие записи и никаких тебе двойников.... А если мы добавляем какие-нибудь другие условия на НЕСОВПАДЕНИЕ типа T1.id<>T2.id или T1.id not in (select id from T2), то оно (как я уже говорил выше) проверяется между записями по принципу 1зап. T1- все зап. T2, 2зап. T1- все зап. T2 и т.д. и естественно несовпадающих дофига и получаем на каждую запись из T1 по куче записей из T2 (которые уже успели совпасть с другими из T1). Так что думаю одним WHERE, без LEFT JOIN и UNION эту задачу нереально решить, но это только мое мнение, к которому я пришел эспериментируя с этими таблицами... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 18:11 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
То АлексейК: Тот код, который я привел, лично у меня дубликатов вроед как не вернул (может я просмотрел, конечно). Но чтобы стопудово их не было, надо тогда тянуть еще и ключевые поля по ним делать условие. Для перестраховки, конечно, можно еще написанть (Not In (SELECT.... )), но думаю, что это лишнее, если правильно организована связь по таблицам. А вот с SELECT ALL как раз и могут быть проблемы ИМХО. а имеющиеся дубликаты не удалятся? Что значит "имеющиеся дубликаты"??? Это как такое возможно, если организовать отбор и условие по ключеванному полю??? Что-то я тут не догнал. :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 18:12 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
2TRoUbLEs: ситуация такая, что между таблицами нет никакой связи, кроме того что они имеют практически одинаковую структуру. По смысловой нагрузке, эти таблицы являются просто двойниками: они приходят в базу из разных источников и их надо сравнить и показать различия (ну и так еще по мелочи...) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 18:20 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
по мелочи - это в этих таблицах есть поле сумма и надо показать записи с несовпадающими суммами Это я думаю к предложенному варианту TRoUbLEs в первый SELECT просто добавить WHERE T1.Summa=T2.Summa ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 18:23 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Блин, вернее T1.Summa<>T2.Summa ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 18:24 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
То SergeySV: Хе. так тогда тебе не WHERE... нужно, а связь попробовать по этим полям сделать. Но хлопотно это. Скорее всего даже не получится, ибо может вылезти огромный гемор. Если тебе надо сравнения, то я бы сначала стал сравнивать Общую сумму (т.е. просуммировал бы две таблички и посмотрел бы сумму). Если они сходятся, значит все гут, если нет, то ищем ошибку. Как вариант, можно попробовать отсортировать мой код по сумме и стоимости и где цифирки не бьются искать проблему. Надеюсь идея понятна. P.S. А вообще, когда стоит задача сравнения данных из несвязанных таблиц, то тут такая морока начинается, если честно. :( Многое, все равно приходится делать ручками. Можно, конечно программно попробовать это сделать (даже небольшой алгоритмик в голове возник), но это такой гемор, что быстрее и качественнее все сделать самому. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 18:47 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Спасибо всем за помощь и предложения. Код предложенный 2TRoUbLEs работает безотказно, двойников нет. 2TRoUbLEs: отдельное спасибо ... :-) правда моя идея с WHERE не прокатывает, че-то Access плюет на это условие, времени уже нет, завтра буду разбираться дальше, хотя странно, почему это... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.09.2003, 18:52 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
C утра разобрался с доп. условием, все оказалось несколько сложнее, чем мне думалось вчера. Мне надо было изменить запрос TRoUbLEs, добавив туда доп. условие: в полях T1.S и T2.S хранится сумма и отобрать надо поля, у которых T1.S<>T2.S. Я вчера наивно думал, что добавив после ON (T1.Id=T2.Id) еще AND (T1.S<>T2.S), все будет путем, однако эта штука прокатила только для первого запроса из этих union - с INNER JOIN. А вот для FROM T1 LEFT JOIN T2 ON (T1.id=T2.id) AND (T1.S<>T2.S) - он делает очень интересную вещь: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Т.е. мы хотели записи Id=3 выкинуть, потому как они T1.S=T2.S, а он ее показал и в полях с [T2.Id], [T2.S] просто пишет NULL. Если конечно хорошо подумать, то он в принципе прав. Ведь он сначала отбирает все записи, которые удовлетворяют между собой условиям: (T1.id=T2.id) AND (T1.S<>T2.S), а потом еще те записи слева(из T1), которые не удовлетворяют указанному условию - вот мы и получаем... хе-хе вообщем в конце рабочего дня до того не всегда сразу допрешь... Чтобы это обойти, я перенес условие (T1.S<>T2.S) в WHERE, добавив туда еще проверку на (T2.S Is Null), весь код: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2003, 10:35 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
То SergeySV: Я тебе сразу указал на гемор, который ты получаешь, если у тебя нет никакой связи между таблицами. (см. 18:47) Но как я смотрю дальше, все-таки какая-то связь есть. :) Я вчера наивно думал, что добавив после ON (T1.Id=T2.Id) еще AND (T1.S<>T2.S) Какой смыл с этом не подскажешь???? Или ты хочеь, чтобы тебе выводились только те записи, которые не совпадают, а совпадающие опустить??? Тогда согласен. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2003, 13:28 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Да, ты правильно понял, по исходной задаче совпадающие записи надо было опустить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2003, 14:13 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Код: plaintext 1. 2. 3. 4. 5. этого должно быть вполне достаточно, если в самих Т1 и Т2 не содержатся повторяющиеся записи. Если содержаться, то будут выведен только 1 экземпляр. UNION - убирает повторяющиеся записи. В LEFT или RIGHT уже содержится INNER. Это что касается OUTER, далее Я вчера наивно думал, что добавив после ON (T1.Id=T2.Id) еще AND (T1.S<>T2.S), все будет путем, однако эта штука прокатила только для первого запроса из этих union - с INNER JOIN. А как же, в INNER ты отбираешь записи с совпадающими ID и не совпадающими суммами. А в LEFT и RIGHT приведенном TroUbLEs коде сверяешь сумму одной записи с суммой несуществующей записи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2003, 15:18 |
|
||
|
Полное внешнее объединение
|
|||
|---|---|---|---|
|
#18+
Признаю себя ослом!!! :-) да, можно и без INNER (а если и использовать INNER, тогда в LEFT/RIGHT надо добавить условие (T2.S Is Nul)/(T1.S Is Nul), т.е. чтобы добавить только отсут. записи слева и справа) В итоге: Код: plaintext 1. 2. 3. 4. 5. 6. 7. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.09.2003, 11:07 |
|
||
|
|

start [/forum/topic.php?fid=45&msg=32256315&tid=1679550]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
69ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
70ms |
get tp. blocked users: |
2ms |
| others: | 209ms |
| total: | 389ms |

| 0 / 0 |
