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

Откуда:
Сообщений: 90
Добрый день всем!

Такая ситуация. Есть три таблицы. t1, t2, t3

t1:
id	val
1	один

t2:
id	val
1	Два
1	Два - вторая

t3:
id	val
1	три
1	Три - вторая


Пишем JOIN
SELECT
	*
FROM
	-------------------------------
	(SELECT
		*
	FROM
		DB.dbo.t1) tab1

	-------------------------------	
	LEFT JOIN
	(SELECT
		*
	FROM
		DB.dbo.t2) tab2
	ON tab1.id = tab2.id

	-------------------------------	
	LEFT JOIN
	(SELECT
		*
	FROM
		DB.dbo.t3) tab3
	ON tab1.id = tab3.id


В результате получаем JOIN первых двух таблиц, и к этому результату JOIN третьей.
id	val		id1		val1			id2	val2
1	один		1		Два			1	три
1	один		1		Два			1	Три - вторая
1	один		1		Два - вторая		1	три
1	один		1		Два - вторая		1	Три - вторая


А как получить такой результат:?
id	val		id1		val1			id2	val2
1	один		1		Два			1	три
1	один		1		Два - вторая		1	Три - вторая
19 мар 18, 12:12    [21267320]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Kopelly
Member

Откуда: Красноярск
Сообщений: 289
Arl,

With 
tab1 as 
(SELECT *,row_number() over (Partition by id order by (Select 1) /*или по желанию Order by val*/) as rn
	FROM DB.dbo.t1),
tab2 as  
(SELECT *,row_number() over (Partition by id order by (Select 1) /*или по желанию Order by val*/) as rn
	FROM DB.dbo.t2),
tab3 as  
(SELECT *,row_number() over (Partition by id order by (Select 1) /*или по желанию Order by val*/) as rn
	FROM DB.dbo.t3)
SELECT
	COALESCE(tab1.id,tab2.id,tab3.id),
	tab1.val,
	tab2.val,
	tab3.val
FROM
	 tab1
	full join tab2 ON tab1.id = tab2.id and tab1.rn = tab2.rn
	full join tab3 ON isnull(tab1.id,tab2.id) = tab3.id and isnull(tab1.rn,tab2.rn) = tab3.rn
19 мар 18, 12:26    [21267372]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Kopelly
Member

Откуда: Красноярск
Сообщений: 289
Arl,
Точнее под ваши выходные данные:

With
tab1 as
(SELECT * DB.dbo.t1),
tab2 as
(SELECT *,row_number() over (Partition by id order by (Select 1) /*или по желанию Order by val*/) as rn
FROM DB.dbo.t2),
tab3 as
(SELECT *,row_number() over (Partition by id order by (Select 1) /*или по желанию Order by val*/) as rn
FROM DB.dbo.t3)
SELECT
tab1.id,
tab1.val,
tab2.id,
tab2.val,
tab3.id,
tab3.val
FROM
tab1
left join tab2 ON tab1.id = tab2.id
left join tab3 ON tab1.id = tab3.id and tab2.rn = tab3.rn
19 мар 18, 12:30    [21267385]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Arl
Member

Откуда:
Сообщений: 90
Спасибо, буду разбираться.
19 мар 18, 12:48    [21267484]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Гигабайт Мегабайтович Килобайтов
Member [заблокирован]

Откуда:
Сообщений: 5975
а чего тут разбираться то ))
если вы сможете объяснить почему записи не должны "размножаться" по правилам множества - то сами и ответите как вам сделать правильный джоин.
19 мар 18, 14:26    [21267878]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Arl
Member

Откуда:
Сообщений: 90
Гигабайт Мегабайтович Килобайтов,
Я ошибочно полагал, что sql server делает второй JOIN к первой таблице, а не к результату JOINа первой и второй таблиц.
19 мар 18, 14:43    [21267985]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Гигабайт Мегабайтович Килобайтов
Member [заблокирован]

Откуда:
Сообщений: 5975
Arl
Гигабайт Мегабайтович Килобайтов,
Я ошибочно полагал, что sql server делает второй JOIN к первой таблице, а не к результату JOINа первой и второй таблиц.

так он и делает к первой таблице )) - только там данных оказывается больше ))
19 мар 18, 18:17    [21269292]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Arl
Member

Откуда:
Сообщений: 90
Гигабайт Мегабайтович Килобайтов,

В таблице t1 запись одна.
После первого JOIN в объединенной таблице становится две записи.
Второй JOIN (таблица t3) идет уже к объединенной таблице с двумя записями (t1 + t2),
и в результате записей становится четыре.

А я думал, что второй JOIN будет к таблице t1 с одной записью.
20 мар 18, 06:05    [21270006]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Гигабайт Мегабайтович Килобайтов
Member [заблокирован]

Откуда:
Сообщений: 5975
Arl
Гигабайт Мегабайтович Килобайтов,

В таблице t1 запись одна.
После первого JOIN в объединенной таблице становится две записи.
Второй JOIN (таблица t3) идет уже к объединенной таблице с двумя записями (t1 + t2),
и в результате записей становится четыре.

А я думал, что второй JOIN будет к таблице t1 с одной записью.

Это вы хотите так "видеть" )) а на самом деле таки объединяет t1 и t3.
потому что если следовать вашей логике , то поменяв порядок джоинов - вы "должны" получить что хотите ))) но это ведь не так? ))
20 мар 18, 09:50    [21270349]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
Arl
Member

Откуда:
Сообщений: 90
Гигабайт Мегабайтович Килобайтов,
Гигабайт Мегабайтович Килобайтов
Это вы хотите так "видеть" )) а на самом деле таки объединяет t1 и t3.

Но ведь в t1 изначально только одна запись...

Я так понимаю, что происходит объединение сначала таблиц t1 и t2, в результате появляются две записи c id = 1,
и уже с этим результатом происходит следующее объединение, и получается 4 записи.
Поправьте, если не прав.
20 мар 18, 11:00    [21270606]     Ответить | Цитировать Сообщить модератору
 Re: JOIN трех таблиц  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
Arl
Гигабайт Мегабайтович Килобайтов,
Гигабайт Мегабайтович Килобайтов
Это вы хотите так "видеть" )) а на самом деле таки объединяет t1 и t3.

Но ведь в t1 изначально только одна запись...

Я так понимаю, что происходит объединение сначала таблиц t1 и t2, в результате появляются две записи c id = 1,
и уже с этим результатом происходит следующее объединение, и получается 4 записи.
Поправьте, если не прав.

да откройте уже план и посмотрите
20 мар 18, 11:04    [21270622]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить