ВНУТРЕННИЙ И ЛЕВЫЙ НАРУЖНЫЕ присоединяются к справке - PullRequest
1 голос
/ 20 мая 2009

Скажите, у меня есть 3 таблицы. Таблица A, Таблица B, Таблица C

Мне нужно использовать набор записей, который доступен после ВНУТРЕННЕГО СОЕДИНЕНИЯ.

Set 1 -> TableA INNER JOIN TableB
Set 2 -> TableC INNER JOIN TableB

Мне нужен набор 1, независимо от того, приходит ли на ум набор 2 или нет (LEFT OUTER JOIN).

По сути, я пытаюсь написать запрос и зашел так далеко

SELECT *
  FROM TableA 
       INNER JOIN TableB ON ...
       LEFT OUTER JOIN (TableC INNER JOIN TableB)

Как мне написать в SQL Server?

РЕДАКТИРОВАТЬ: На самом деле, я пытаюсь объединить несколько столов. Как изменится ваш ответ, если мне нужно объединить несколько таблиц, например: OUTER JOIN OF (INNER JOIN of TableA и TableB) и (INNER JOIN OF TableC и TableD)

Ответы [ 9 ]

4 голосов
/ 21 мая 2009
 SELECT * FROM TableA 
       INNER JOIN TableB ON TableB.id = TableA.id
       LEFT JOIN TABLEC ON TABLEC.id = TABLEB.id

Я не знаю, какие колонки вы пытаетесь использовать, но это так просто

Edit: Глядя на ваши изменения, кажется, что вы не понимаете, что на самом деле делают Joins. В приведенном выше примере вы получите следующие результаты.

Столбцы -> Вы получите все столбцы для TableA, TableB и TableC

Rows-> Вы начнете со всех строк из таблицы A. Затем вы удалите все строки из Таблицы A, которые не имеют совпадающего «идентификатора» в Таблице B. (У вас будут дубликаты, если между TableA и TableB нет отношения 1: 1).

Теперь, если вы возьмете результаты сверху, вы сопоставите любые записи из TableC, которые соответствуют столбцу TableB.id. Любые строки сверху, у которых нет соответствующей записи TableC, получат нулевое значение для всех столбцов из TableC в результатах.

СОВЕТ. Я держу пари, что только часть этого имела для вас смысл, но я советую вам начать писать некоторые запросы, прогнозировать результаты, а затем проверять правильность своих прогнозов, чтобы понять, понимаете ли вы, что он делает. 1012 *

2 голосов
/ 21 мая 2009

Вы можете добавить порядок в свои объединения, как в математическом уравнении, где вы можете сделать это: (5 + 4) * (3 + 1).

Учитывая вторую часть вашего вопроса, попробуйте:

SELECT
     <your columns>
FROM
     (TableA INNER JOIN Table B ON <join criteria for A to B>)
LEFT OUTER JOIN
     (TableC INNER JOIN Table D ON <join criteria for C to D>) ON
     <join criteria for AxB to CxD>
2 голосов
/ 21 мая 2009

То, что вы хотите, это не СОЕДИНЕНИЕ, а СОЮЗ.

SELECT * FROM TableA INNER JOIN TableB ON ...
UNION
SELECT * FROM TableC INNER JOIN TableD ON ...
1 голос
/ 21 мая 2009
Select * from ((((TableA a inner join TableB b on a.id = b.id) 
                left outer join TableC c on b.id = c.id)
                full outer join TableD d on c.id = d.id)
                right outer join TableE e on e.id = d.id)
                /* etc, etc... */

Вы можете потерять скобки, если хотите.

0 голосов
/ 21 мая 2009
SELECT *
  FROM TableA A
 INNER JOIN TableB B  ON B.?? = A.??  AND ...
  LEFT JOIN TableC C  ON C.?? = B.??  AND ...
  LEFT JOIN TableB B2 ON B2.?? = C.?? AND ...
  LEFT JOIN TableD D  ON D.?? = C.??  AND ...

Так вот в чем дело: логически, объединения на самом деле не между конкретными таблицами, а между таблицей и остальной частью "набора" (объединений и таблиц). Таким образом, в то время как вы знаете, что между C и B2 или между C и D существует отношение 1: 1, вы не можете присоединиться к C, поскольку C может быть нулевым из это ЛЕВОЕ СОЕДИНЕНИЕ к B, которое удалит эти строки, фактически отменяя ваше ЛЕВОЕ соединение.

Таким образом, в принципе, любые соединения с таблицей, которые являются левыми внешними связями, также должны быть левыми внешними связями. Имеет ли это смысл?

0 голосов
/ 21 мая 2009

Поскольку вы используете Sql Server, почему бы не создать представления, которые вам помогут? Наполнение всего в гигантском Sql утверждении может стать трудным для чтения. Пример представления может выглядеть следующим образом:

create view AandB
as
select *
from A
inner join B on B.aid = A.aid

И то же самое для CandD. Затем вы можете получить необязательное соединение с помощью простого Sql:

select *
from AndB
left outer join CandD on AndB.cid = CandD.cid

Если вас интересуют строки из обоих наборов, вы можете выполнить полное объединение:

select *
from AndB
full outer join CandD on AndB.cid = CandD.cid
0 голосов
/ 21 мая 2009

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

SELECT a.a_id, b1.b_id b1_id, b2_id, bc.c_id
FROM TableA a JOIN TableB b1 on a.b_id = b1.b_id
LEFT JOIN (SELECT c.c_id, b2.b_id b2_id
    FROM TableC c JOIN TableB b2 ON c.b_id = b2.b_id
  ) bc ON bc.c_id = a.c_id;

Глядя на ваше последнее редактирование, вы можете сделать что-то вроде:

SELECT <columns>
FROM (SELECT <columns> FROM TableA JOIN TableB ON <A-B join conditions>)
           LEFT JOIN
           (SELECT <columns> FROM TableC JOIN TableD ON <C-D join conditions>)
           ON <AB-CD join conditions>

Хотя вам на самом деле не нужны внутренние проекции, и вы можете делать:

SELECT <columns>
FROM (TableA a JOIN TableB b ON <A-B join conditions>)
           LEFT JOIN
           (TableC c JOIN TableD d ON <C-D join conditions>)
           ON <AB-CD join conditions>

В тех случаях, когда условия соединения AB-CD записываются непосредственно в виде столбцов a, b, c, d и т. Д.

0 голосов
/ 21 мая 2009

Предполагая, что я понимаю ваш вопрос, я думаю, это то, что вы просите:

SELECT * 
FROM TableA INNER JOIN TableB on TableA.JoinColumn = TableB.JoinColumn
LEFT OUTER JOIN TableC on TableB.JoinColum = TableC.JoinColumn
INNER JOIN TableD on TableC.JoinColumn = TableD.JoinColumn

Обратите внимание, что столбец JoinColumn, используемый для присоединения к A & B, не обязательно должен быть тем же столбцом, что и столбец, используемый для присоединения к B & C, и так далее для C & D.

0 голосов
/ 21 мая 2009

попробуйте это ..

SELECT *
  FROM TableA              a 
       INNER JOIN TableB   b ON a.id=b.id
       LEFT OUTER JOIN (SELECT *
                            FROM TableC            c
                                INNER JOIN TableD  d on c.id=d.id
                       ) dt on b.id=dt.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...