【问题标题】:Oracle SQL: Proper way to join for this query?Oracle SQL:加入此查询的正确方法?
【发布时间】:2011-07-26 13:33:04
【问题描述】:

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

这是表格

  1. 火车:火车列表 (choo-choooo) 和火车长度(以货车数量计)
  2. WTA:货车吨数 A - 位置 A 列车中货车的重量
  3. WTB:货车吨数 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:我的解决方案是否正确?如果是这样,我该如何实施?

【问题讨论】:

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


    【解决方案1】:

    您的方法会奏效,但我认为 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
    

    【讨论】:

    • 太棒了 :) 我正在使用 oracle,所以我应该能够使用完全连接。你能建议这将如何改变你编写的 SQL 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-12
    • 2015-07-09
    • 1970-01-01
    相关资源
    最近更新 更多