在多列上连接多个表

时间:2013-10-02 15:32:23

标签: sql oracle

我也有一个关于如何加入我的数据库表的问题。我的数据设置如下:

MainTable
main_id x y z
1       l m n
2       o p q
SubTableA
main_id extra_id foo bar
1       a        1   4
1       b        2   h
1       c        1   g
2       a        k   er
2       b        k   34
2       c        l   f

SubTableB
main_id extra_id a b c
1       a        v r j
1       c        w r k
2       c        x h l

SubTableC
main_id extra_id mono stereo
2       c        n    null
2       d        z    y

我正在努力实现以下结果:

main_id x y z extra_id foo bar a b c mono stereo
1       l m n a        1   4   v r j null null
1       l m n b        2   h         null null
1       l m n c        1   g   w r k null null
2       o p q a        k   er        null null
2       o p q b        k   34        null null
2       o p q c        l   f   x h l n    null
2       o p q d                      z    y

为了增加趣味,有时候extra_id为空或其中一个子表不包含main_id但是我希望其他表连接并填充空值以获取值找不到。
在那种情况下,我希望结果是:
例如main_id x y z extra_id foo bar a b c null null

我尝试使用How can I join multiple SQL tables using the IDs?作为模板,但无法一直使用它。

这是我到目前为止所尝试的:

SELECT
  m.*,
  a.*,
  b.*,
  c.*,
FROM
  MainTable m,
  SubTableA a,
  SubTableB b,
  SubTableC c,
WHERE
  m.main_id = a.main_id(+)
  AND a.main_id=b.main_id(+)
  AND a.extra_id=b.extra_id(+)
  AND a.main_id = c.main_id(+)
  AND a.extra_id = c.extra_id(+);

编辑:
我想要主表中的所有行。当它们匹配main_id上的子表时,为每个extra_id(每个main_id可以多于一个)连接它们。如果main_id和extra_id的组合存在于多个子表中,我希望它们被连接起来。再次在笔记本电脑前会给出更详细的例子。

SQLFiddle

谢谢,
基督教

2 个答案:

答案 0 :(得分:1)

让我们来看看你的联接。您想要将Main连接到A,但保留A中存在的所有行但没有main_id,对吧?所以你想要从连接的右侧一切。

MainTable M RIGHT JOIN SubTableA A ON M.main_id = A.main_id

你希望所有表都这样做;

SELECT
    A.*
    , B.*
    , C.*
FROM
    MainTable M
     RIGHT JOIN SubTableA A ON M.main_id = A.main_id
     RIGHT JOIN SubTableB B ON M.main_id = B.main_id
     RIGHT JOIN SubTableC C ON M.main_id = C.main_id

WHERE
[some stuff]

注意:您可能需要尝试RIGHT OUTER JOIN。 注2:我对描述感到困惑。如果该行存在于Main但不存在于子表中,那么您需要LEFT - Main中的所有行,无论它们是否存在于连接的另一侧。如果该行存在于子表中但不存在于Main中,那么您需要一个RIGHT OUTER。

P.S。我没有意识到这是针对Oracle的,所以我希望它没有太大的不同。

答案 1 :(得分:1)

此答案假设您希望加入,而不是右加入 - 换句话说,即使MainTable中没有相关行,也始终显示来自SubTableA的行其他。这是由monostereo的空值示例输出所暗示的。

我转移到较新的连接语法,当您想要包含列时,您应该命名它而不是依赖SELECT *SELECT *适用于快速,即席查询,但对于更多内容,您应该为列命名。

我还建议使用别名来减少打字。考虑到您的示例中的SCAD,看起来您正在这样做。

SELECT
  m.main_id,
  m.x,
  m.y,
  m.z,
  a.extra_id,
  a.foo,
  a.bar,
  b.a,
  b.b,
  b.c,
  c.mono,
  c.stereo
FROM MainTable m
LEFT JOIN SubTableA a
  ON m.main_id = a.main_id
LEFT JOIN SubTableB b
  ON a.main_id = b.main_id AND a.extra_id = b.extra_id
LEFT JOIN SubTableC c
  ON a.main_id = b.main_id AND a.extra_id = c.extra_id