Как сделать внешнее соединение на> 2 таблицах (Oracle) - PullRequest
7 голосов
/ 16 сентября 2010

Я не уверен, как описать структуру моей таблицы, поэтому надеюсь, что это имеет смысл ...

У меня есть 3 таблицы в иерархических отношениях, так что A имеет отношение один ко многим с B, которое, в свою очередь, имеет отношение один ко многим с C. Хитрость заключается в том, что внешнему ключу в B и C разрешено быть нулевым ( т.е. родитель не определен). У меня также есть D и E без отношения к A, B или C (напрямую).

Наконец, у меня есть F, которая является таблицей соединения со многими отношениями один к одному с C, D и E. Ни одно из ее полей (FK для других таблиц) не может быть обнулено.

Я хотел бы написать оператор SQL, который объединяет все таблицы в один набор результатов. Я знаю, что должен использовать внешние соединения, потому что я хочу, чтобы все A возвращалось независимо от того, есть ли у них дочерние элементы в B и подобные с B и C.

Вопрос первый: Я изучал синтаксис внешнего соединения ANSI (раньше я использовал только Oracle ((+))) и не могу найти пример, когда внешнее объединяет более двух таблиц. Может ли кто-нибудь предоставить / указать на пример?

Вопрос второй: Можно ли включить записи из таблиц D и E на основе таблицы соединения F? Если это так, это делается с внешними объединениями?

Спасибо!

EDIT

Конечно, сразу после того, как я опубликовал это, я нашел пример, который отвечает на вопрос 1. Однако вопрос 2 все еще ставит меня в тупик.

Пример: * * тысяча двадцать-пять

         SELECT A.a,
                B.b,
                C.c
           FROM A
FULL OUTER JOIN B ON B.a = A.a
FULL OUTER JOIN C ON C.b = B.b

Ответы [ 4 ]

9 голосов
/ 16 сентября 2010

Итак, я визуализирую вашу схему следующим образом:

A --o< B --o< C --< F >-- D
                      >-- E

Вы, безусловно, можете выполнять несколько объединений, а также группировать выражения объединения с круглыми скобками, точно так же, как вы можете группировать арифметические выражения.

SELECT ...
FROM A LEFT OUTER JOIN (
  B LEFT OUTER JOIN (
    C LEFT OUTER JOIN (
      F INNER JOIN D ON D.d = F.d
        INNER JOIN E ON E.e = F.e
      ) ON C.c = F.c
    ) ON B.b = C.b
) ON A.a = B.a

Эти круглые скобки не подзапросы, они просто группируют операции соединения.

1 голос
/ 27 сентября 2010

Для пояснения заглавные буквы относятся к таблицам, а строчные - к столбцам первичного / внешнего ключа. Вероятно, мне следовало написать его, похожий на Quassnoi, но я буду придерживаться этого, поскольку именно так все и началось.

Этот SQL возвращает результаты, для которых я ищу:

         SELECT A.a,
                B.b,
                C.c,
                D.d,
                E.e
           FROM A
FULL OUTER JOIN B ON B.a = A.a
FULL OUTER JOIN C ON C.b = B.b
FULL OUTER JOIN F ON F.c = C.c
FULL OUTER JOIN D ON D.d = F.d
FULL OUTER JOIN E ON E.e = F.e

Я пытался настроить свой SQL, как у Билла, но использовал полные объединения вместо левых, но он не дал те же результаты, что и мой. Я не могу сказать, что полностью понимаю его SQL, но соединения INNER отфильтровали некоторые результаты.

1 голос
/ 16 сентября 2010
 select a.*, b.*, c.*
 from a
 left outer join b on a.b_id = b.id
 left outer join c on a.c_id = c.id

Теперь ввод D, E & F становится сложнее:

select c.*, d.*, e.*
from C
inner join f on c.id = f.c_id
inner join d on d.id = f.d_id
inner join e on d.id = f.e_id

Тогда мы сложим все вместе:

 select a.*, b.*, cde.*
 from a
 left outer join b on a.b_id = b.id
 left outer join 
 (select c.id as c_id, c.*, d.*, e.*
   from C
   inner join f on c.id = f.c_id
   inner join d on d.id = f.d_id
   inner join e on d.id = f.e_id) CDE
 on a.c_id = cde.c_id
0 голосов
/ 16 сентября 2010
SELECT  a.*, b.*, c.*, d.*, e.*
FROM    a
LEFT JOIN
        b
ON      b.a = a.id
LEFT JOIN
        с
ON      c.b = b.id
LEFT JOIN
        f
ON      f.с = c.id
LEFT JOIN
        d
ON      d.id = f.d
LEFT JOIN
        e
ON      e.id = f.e
...