Oracle SQL:正确加入此查询的方法?

时间:2011-03-31 02:17:39

标签: sql oracle join left-join inner-join

我有三个不同的表,我正在尝试正确加入,但我遇到了一些问题。

以下是表格

  1. 火车:火车列车(choo-choooo)和火车车厢长度
  2. WTA:Wagon Tonnes A - 位置A的火车车厢重量
  3. WTB:Wagon Tonnes B - 位置B的火车车厢重量
  4. 问题:从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 个答案:

答案 0 :(得分:3)

您的方法可行,但我认为将LEFT JOIN更容易组合到代表WTA和WTB超集的组合数据集。由两部分组成的UNION ALL模拟了MySQL中缺少的FULL JOIN。

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