Oracle SQL: правильный способ присоединиться к этому запросу? - PullRequest
1 голос
/ 31 марта 2011

У меня есть три разные таблицы, которые я пытаюсь правильно объединить, но у меня возникают некоторые проблемы.

Вот таблицы

  1. Поезд: список поездов (choo-choooo) и длина поезда в количестве вагонов
  2. WTA: Wagon Tonnes A - Масса вагонов в поезде в местоположении A
  3. WTB: Wagon Tonnes B - Вес вагонов в поезде в местоположении B

Проблема: некоторые поезда полностью отсутствуют в одной или двух таблицах WagonTonnes. Некоторые отдельные вагоны отсутствуют в таблицах WagonTonnes. И я хочу, чтобы мой запрос показывал эти случаи как нулевые, если их не было.

Сначала я попытался сделать это, и он отлично работает.

select 
 train.id,
 train.length,
 a.position_in_train
 a.tonnes,
from 
 train
 left outer join wta a
 using (train_id)

Теперь я хочу добавить левое внешнее объединение для b, вот так

select 
 train.id,
 train.length,
 a.position_in_train
 a.tonnes,
 b.position_in_train,
 b.tonnes
from 
 train
 left outer join wta a
 using (train_id)
 left outer join wtb b
 using (train_id)

Но это идет наперекосяк и повторяет один и тот же результат строки снова и снова.

Предлагаемое решение

Я подозреваю, что мне как-то нужно получить запрос с поезда, который вместо того, чтобы выглядеть так,

train.id train.length
7        163 

выглядит так

train.id train.position
7        1 
7        2 
7        3
7        4
...      ...
7        162
7        163

А затем переписать мои объединения, чтобы они выглядели так:

left outer join wta a
on (a.train_id = train.train_id and a.position = train.position)

Вопрос 1: Правильный ли мой общий подход к этой проблеме? (Присоединиться к мудрым)

Вопрос 2: Правильно ли мое решение? Если да, то как я могу это реализовать?

1 Ответ

3 голосов
/ 31 марта 2011

Ваш подход будет работать, но я думаю, что легче ПРИСОЕДИНИТЬСЯ к объединенному набору данных, представляющему расширенный набор WTA и WTB. UNION ALL, состоящий из двух частей, эмулирует FULL JOIN, которого нет в MySQL.

select 
 t.id,
 t.length,
 wt.a_position_in_train,
 wt.a_tonnes,
 wt.b_position_in_train,
 wt.b_tonnes
from train t
left join (
    select a.train_id,
        a.position_in_train a_position_in_train, a.tonnes b_tonnes,
        b.position_in_train b_position_in_train, b.tonnes b_tonnes
    from wta a left join wtb b on a.train_id = b.train_id and a.position_in_train = b.position_in_train
    union all
    select b.train_id, a.position_in_train, a.tonnes, b.position_in_train, b.tonnes
    from wta b left join wtb a on a.train_id = b.train_id and a.position_in_train = b.position_in_train
    where a.train_id is null
) wt on t.train_id = wt.train_id
order by t.train_id, coalesce(a_position_in_train, b_position_in_train)

Заморозка мозгов, для Oracle FULL JOIN будет (внутренний запрос)

    select coalesce(a.train_id, b.train_id) train_id,
        a.position_in_train a_position_in_train, a.tonnes b_tonnes,
        b.position_in_train b_position_in_train, b.tonnes b_tonnes
    from wta a full join wtb b
        on a.train_id = b.train_id and a.position_in_train = b.position_in_train
...