2

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

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_idis null 或其中一个子表不包含main_id,但我希望其他表被连接并为未找到的值填充空值。
在那种情况下,我希望结果是:
main_id x y z extra_id foo bar a b c null null例如。

我尝试使用如何使用 ID 连接多个 SQL 表?作为模板,但无法一路获得。

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

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

谢谢,
克里斯蒂安

4

2 回答 2

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。

PS我没有意识到这是针对Oracle的,所以我希望它不会太不同。

于 2013-10-02T15:39:51.967 回答
1

此答案假定您想要连接,而不是右连接 - 换句话说,MainTable即使没有相关行SubTableA和其他行,也始终显示行。mono和为空值的示例输出暗示了这一点stereo

我会转向更新的连接语法,当你想要包含一个列时,你应该命名它而不是依赖SELECT *. SELECT *对于快速的即席查询来说很好,但对于其他任何内容,您应该为列命名。

我还建议使用别名来减少打字。鉴于您的示例中的SCand ,您似乎正在这样做。AD

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
于 2013-10-02T15:46:08.753 回答