2014-01-17 3 views
1

Впервые в моей профессиональной карьере я нашел необходимость в объединении результата объединения со столом, являющимся первым соединением внутреннего соединения, а вторым - с внешним внешним соединением.Внешнее левое соединение внутреннего соединения и регулярного стола

Я пришел к этому решению:

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

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

Действительно ли этот код? Я получил согласованные результаты, но я хотел бы проверить, теоретически ли это правильно. Есть ли у вас предложения по улучшению этого подхода?

ответ

1

Да, это правильно, но это не делает ничего другого, чем то же самое (простой) запрос без скобок :

SELECT * 
FROM TableA 
     INNER JOIN TableB 
      ON TableA.foreign = TableB.id 
     LEFT OUTER JOIN TableC 
      ON TableC.id = TableB.id; 

SQL Fiddle showing both queries with the same result

Также стоит отметить, что оба запроса имеют точно такой же план выполнения

Скобки используются, когда вам нужно налево присоединиться по результатам внутреннего соединения, например, Если вы хотите, чтобы вернуться только результаты из таблицы б где была запись в tableC, но все еще остается присоединиться к TableA вы могли бы написать:

SELECT * 
FROM TableA 
     LEFT OUTER JOIN TableB 
      ON TableA.foreign = TableB.id 
     INNER JOIN TableC 
      ON TableC.id = TableB.id; 

Однако это эффективно превращает LEFT OUTER JOIN на TableB в внутреннее соединение, потому что ВХОДНОЙ ПОДГОТОВКИ ниже. В этом случае вы должны использовать круглые скобки, чтобы изменить инфу в соответствии с требованиями:

SELECT * 
FROM TableA 
     LEFT OUTER JOIN (TableB 
     INNER JOIN TableC 
      ON TableC.id = TableB.id) 
      ON TableA.foreign = TableB.id; 

SQL Fiddle to show difference in results when adding parentheses

2

Вы должны сделать это более простым способом.

SELECT * FROM 
TableA 
INNER JOIN TableB ON TableA.foreign = TableB.id 
LEFT OUTER JOIN TableC ON TableB.id = TableC.id 

Обычно это делается таким образом.

1

Я считаю, что вы ищете что-то вроде этого:

SELECT *, t.otherFields 
FROM 
(
    SELECT TableB.id, otherFields FROM TableA 
    INNER JOIN TableB ON 
    TableA.foreign = TableB.id 
) t 
LEFT OUTER JOIN TableC 
ON TableC.id = t.id 
1
SELECT * 
FROM TableA 
    INNER JOIN TableB ON 
     TableA.foreign = TableB.id 
LEFT OUTER JOIN TableC 
    ON TableC.id = TableB.id 

Также отлично

Смежные вопросы