Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Microsoft SQL Server 2012 - 11.0.2100.60 (X64)

Задача: если в таблицах t3 и t4 не будет записей, показывать только t1.*

(1-ый запрос)
SELECT t1.*, t3.ad, t4.ac
FROM tab1 t1
    LEFT JOIN tab2 t2
    ON t1.a= t2.a
    INNER JOIN tab3 t3
    ON t2.c = t3.c
    INNER JOIN tab4 t4
    ON t2.d = t4.d

(2-ой запрос)
SELECT t1.*, t3.ad, t4.ac
FROM tab1 t1
    LEFT JOIN tab2 t2
        INNER JOIN tab3 t3
        ON t2.c = t3.c
        INNER JOIN tab4 t4
        ON t2.d = t4.d
    ON t1.a= t2.a

эквивалентны ли эти запросы?
Почему первый запрос может вернуть пустоту, если нет данных в t3 и t4?
4 дек 12, 18:03    [13577069]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
Glory
Member

Откуда:
Сообщений: 104751
Люк, используй скобки. Они работают и для JOIN-ов. Как и для выражений. Для определения порядка операций
4 дек 12, 18:15    [13577129]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Glory,

Пожалуйста приведите пример со скобками, пока не догадался как их расставить.
4 дек 12, 18:32    [13577216]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
Glory
Member

Откуда:
Сообщений: 104751
select * 
from syscolumns a
left outer join (sysobjects c inner join sysindexes d on c.id=d.id) on a.id = c.id
4 дек 12, 18:39    [13577258]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
trew
Member

Откуда: Москва
Сообщений: 2646
Glory,

Спасибо за пример!
4 дек 12, 19:54    [13577589]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 47105
Скобки в JOINах не играют никакой роли и имеют декоративное значение.
Никакой порядок соединений они не определяют.
4 дек 12, 20:21    [13577678]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
iap
Скобки в JOINах не играют никакой роли и имеют декоративное значение.
Никакой порядок соединений они не определяют.

Точно?
4 дек 12, 21:04    [13577802]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 47105
SomewhereSomehow
iap
Скобки в JOINах не играют никакой роли и имеют декоративное значение.
Никакой порядок соединений они не определяют.

Точно?
Зуб даю!
4 дек 12, 21:29    [13577883]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
Alexander Titkin
Member

Откуда: Москва
Сообщений: 91
trew,

Left join даст на выходе как Inner join, если к нему далее Inner join. Правило простое: если таблица идет с left join, то и все таблицы, ссылающиеся на нее должны быть с left join. Иначе смысла нет
4 дек 12, 23:48    [13578237]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
Добрый Э - Эх
Guest
Glory
select * 
from syscolumns a
left outer join (sysobjects c inner join sysindexes d on c.id=d.id) on a.id = c.id

Glory, позволь тут с тобой не согласиться и присоединиться к IAP-у в его высказывании:
iap
Скобки в JOINах не играют никакой роли и имеют декоративное значение.
Никакой порядок соединений они не определяют.


Тут на результат запроса влияют не скобки, расставленные между джойнами, а порядок следования фраз ON. Просто скобки нагляднее позволяют этот порядок увидеть. Сравни:
with
  t1(num1) as 
    (select * from (values (1),
                           (2),
                           (3)
                   ) as v(n)
    ),
  t2(num2) as
    (select * from (values (1),
                           (2)  
                   ) as v(n)
    ),
  t3(num3) as
    (select * from (values (1)
                   ) as v(n)
    )
--
--
select *
  from t1
  left join (t2
       join t3
         on t2.num2 = t3.num3)
    on t1.num1 = t2.num2


и

with
  t1(num1) as 
    (select * from (values (1),
                           (2),
                           (3)
                   ) as v(n)
    ),
  t2(num2) as
    (select * from (values (1),
                           (2)  
                   ) as v(n)
    ),
  t3(num3) as
    (select * from (values (1)
                   ) as v(n)
    )
--
--
select *
  from t1
  left join t2
       join t3
         on t2.num2 = t3.num3
    on t1.num1 = t2.num2

Легко видеть, что результат идентичен - что со скобками, что без...
5 дек 12, 04:51    [13578552]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 47105
Alexander Titkin
trew,

Left join даст на выходе как Inner join, если к нему далее Inner join. Правило простое: если таблица идет с left join, то и все таблицы, ссылающиеся на нее должны быть с left join. Иначе смысла нет
Это не совсем так, строго говоря.
В условии INNER JOIN можно предусмотреть возможность наличия NULLов в полях.
5 дек 12, 09:18    [13578919]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Все так, только вот интересно, во всех ли случаях, потому что
BOL
<joined_table>
Is a result set that is the product of two or more tables. For multiple joins, use parentheses to change the natural order of the joins

FROM (Transact-SQL)
Либо это просто неточность в документации, либо есть какие-то нюансы.
5 дек 12, 11:15    [13579645]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 47105
SomewhereSomehow
Все так, только вот интересно, во всех ли случаях, потому что
BOL
<joined_table>
Is a result set that is the product of two or more tables. For multiple joins, use parentheses to change the natural order of the joins

FROM (Transact-SQL)
Либо это просто неточность в документации, либо есть какие-то нюансы.
Положение скобок однозначно определяется расположением ключевых слов JOIN и ON.
Поставить скобки в другие места просто не получится - будет сообщение о синтаксической ошибке.
В то же время сервер эти скобки и не требует.
Отсюда я и делаю вывод об их декоративной функции
5 дек 12, 11:36    [13579850]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
iap,

Я понял, но я не совсем про это, я про наличие/отсутствие.
Вот например:
declare @t1 table(a int primary key);
declare @t2 table(a int primary key);
declare @t3 table(a int primary key);
select
	*
from
	(@t1 t1 join @t3 t3 on t1.a = t3.a)
	join @t2 t2 on t1.a = t2.a

select
	*
from
	@t1 t1 join @t3 t3 on t1.a = t3.a
	join @t2 t2 on t1.a = t2.a

Всегда соединяет в порядке t1->t2->t3 - что есть скобки, что нет скобок.
И вот я задумался, учитывая фразу в документации, во всех ли случаях он плюет на скобки и переупорядочивает в соответствии с эвристиками.
5 дек 12, 12:12    [13580148]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 47105
SomewhereSomehow,

Если бы скобки влияли на порядок JOINов, то зачем сделали хинт FORCE ORDER?
5 дек 12, 12:19    [13580221]     Ответить | Цитировать Сообщить модератору
 Re: Как работает LEFT JOIN если далее к нему INNER JOIN  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
iap,

Это вопрос не ко мне, я его не делал=)
Все-таки в документации, довольно странная, на мой взгляд, фраза...
5 дек 12, 12:48    [13580503]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить