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

Откуда: Кишинёв
Сообщений: 6724
В продолжении темы Треугольный LEFT FULL JOIN
Нормальный вариант:
            Table1
 LEFT  JOIN Table2
       JOIN Table3	ON Table3 <-> Table2
			ON (Table3, Table2) <-> Table1
Облом:
            Table1
 LEFT  JOIN Table2
CROSS APPLY FuncT3(Table2)
			ON (FuncT3, Table2) <-> Table1
Непродуманно это всё.
6 мар 12, 15:56    [12204429]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Неужели непонятен смысл проблемы из запроса?
Или это всё капитански? (Т.е. ЖДВББАСЁФ.)

Или тупо: Не до этого сейчас, когда тут такое творится ...
6 мар 12, 17:52    [12205746]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Crimean
Member

Откуда:
Сообщений: 13147
судя по исходному посту смысл проблемы в организации данных
собственно это и приводит к лишним сканам таблиц и/или (смотря с какой стороны смотреть) к "ужасного вида" конструкциям
"нормально" там таки "должно быть" несколько сканов одних и тех же таблиц, хотя это и неприятно
6 мар 12, 18:06    [12205851]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Crimean
судя по исходному посту смысл проблемы в организации данных
собственно это и приводит к лишним сканам таблиц и/или (смотря с какой стороны смотреть) к "ужасного вида" конструкциям
О боже что не создам топик, так сразу лечить.
Где вы там увидели сканы и плохую организацию ????
Нет там никаких лишних сканов.

1-я консрукция заявленая / работающая, используемая
2-я консрукция имеет тот же смысл, но с другим интерфейсом, но невозможная по текущему синтаксису

Это конструкция несёт конкретный смысл, кошерность проектирования БД тут не причём совершенно.

В первоначальном посте смысл был именно в слабой мощности базового языка SQL.
В данном случае смысл в плохой продуманности оператора APPLY, введёного M$.
И эта проблема есть порождение первой.

Crimean, -1 вам за немнимательность. Реабелитируйтесь пожайлуста.
Может мне надо было скобочки в JOIN-ах расставить?
6 мар 12, 20:41    [12206516]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Crimean
Member

Откуда:
Сообщений: 13147
про треугольники - @base 2 раза сканить
про APPLY - примерчик, непонятно
6 мар 12, 20:59    [12206575]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Crimean
про треугольники - @base 2 раза сканить
С чё та? 10724946 Там просто много наводящих рассуждений.
Crimean
про APPLY - примерчик, непонятно
Таблы:
Table1
ID Name
1 A
2 B
3 C

Table2
ID Name
1 A1
2 B1

Table3
ID Name
1 A2
3 C2
SELECT	*
FROM	           Table1 T1
	LEFT  JOIN(Table2 T2
	      JOIN Table3 T3 ON T3.ID = T2.ID
			   ) ON T2.ID = T1.ID -- AND T3... = T1...
ID Name1 Name2 Name3
1 A A1 A2
2 B
3 C

---------------------------------------------------------------
CREATE FUNCTION [dbo].[fnFunc3] (
	 @ID	Int
) RETURNS TABLE AS RETURN
	-- Сложная скрытая функциональность
	SELECT	*
	FROM	Table3
	WHERE	ID = @ID
GO
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN (Table2		T2
	CROSS APPLY dbo.fnFunc3(T2.ID)	T3
					) ON T2.ID = T1.ID -- AND T3... = T1...
-- Ошибка синтаксиса, наслаждайтесь обходными извратами:
SELECT	*
FROM	            Table1 		T1
	OUTER APPLY(
		SELECT	*
		FROM	Table2		T2
			CROSS APPLY dbo.fnFunc3(T2.ID)	T3
		WHERE	T2.ID = T1.ID  -- AND T3... = T1...
	) X -- Это только в примерах терпимо
7 мар 12, 02:13    [12207410]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3058
либо я ещё не проснулся, либо ...

К сообщению приложен файл. Размер - 14Kb
7 мар 12, 08:28    [12207607]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Crimean
Member

Откуда:
Сообщений: 13147
HandKot,

у меня пока тоже все 3 примера без ошибок дают одинаковые результаты
7 мар 12, 11:52    [12208740]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Andrey Sribnyak
Member

Откуда: Киев
Сообщений: 600
Crimean,

НУ у меня третий был изначально с ошибками... но они легко правятся... а так да, одинакове
create table dbo.table1 (id int, Name nvarchar(5))
go
create table dbo.table2 (id int, Name nvarchar(5))
go
create table dbo.table3 (id int, Name nvarchar(5))
go
CREATE FUNCTION [dbo].[fnFunc3] (
	 @ID	Int
) RETURNS TABLE AS RETURN
	-- Сложная скрытая функциональность
	SELECT	*
	FROM	Table3
	WHERE	ID = @ID
GO
insert into dbo.table1 values (1,'A'),(2,'B'),(3,'C')
insert into dbo.table2 values (1,'A1'),(2,'B1')
insert into dbo.table3 values (1,'A2'),(3,'C2')

SELECT	*
FROM	           Table1 T1
	LEFT  JOIN(Table2 T2
	      JOIN Table3 T3 ON T3.ID = T2.ID
			   ) ON T2.ID = T1.ID
			   
			   
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN (Table2		T2
	CROSS APPLY dbo.fnFunc3(T2.ID)	T3
					) ON T2.ID = T1.ID -- AND T3... = T1...
-- Ошибка синтаксиса, наслаждайтесь обходными извратами:

SELECT	*
FROM	            Table1 		T1
	OUTER APPLY(
		SELECT	t2.id as id2, t2.Name as name2, t3.*
		FROM	Table2		T2
			CROSS APPLY dbo.fnFunc3(T2.ID)	T3
		WHERE	T2.ID = T1.ID  -- AND T3... = T1...
	)q  -- Это только в примерах терпимо
			   

drop table dbo.table1
drop table dbo.table2
drop table dbo.table3
drop function [dbo].[fnFunc3]
7 мар 12, 12:32    [12209084]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724

Посыпаю голову пеплом. Ссори за невнимательность.

И даже так работает:
USE tempdb
GO
CREATE TABLE dbo.Table1 (ID Int PRIMARY KEY, Name NVarChar(5))
CREATE TABLE dbo.Table2 (ID Int PRIMARY KEY, Name NVarChar(5))
CREATE TABLE dbo.Table3 (ID Int PRIMARY KEY, Name NVarChar(5))
GO
CREATE FUNCTION [dbo].[fnFunc3] (
	 @ID	Int
) RETURNS TABLE AS RETURN
	-- Сложная скрытая функциональность
	SELECT	*
	FROM	Table3
	WHERE	ID = @ID
GO
INSERT dbo.table1 VALUES (1,'A'),(2,'B'),(3,'C')
INSERT dbo.table2 VALUES (1,'A1'),(2,'B1')
INSERT dbo.table3 VALUES (1,'A2'),(3,'C2')

SELECT	*
FROM	           Table1 T1
	LEFT  JOIN Table2 T2
	      JOIN Table3 T3 ON T3.ID = T2.ID
			     ON T2.ID = T1.ID
			    AND T3.ID = T1.ID

SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN  Table2		T2
	CROSS APPLY dbo.fnFunc3(T2.ID)	T3
					 ON T2.ID = T1.ID
					AND T3.ID = T1.ID
GO
DROP FUNCTION [dbo].[fnFunc3]
DROP TABLE dbo.table1
DROP TABLE dbo.table2
DROP TABLE dbo.table3
GO

Мда видимо ошибка на моём реальном примере была в другом. Нагрузка сказывается.

... Но вот вариант который не работает:
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN  Table2		T2
	CROSS APPLY dbo.fnFunc3(T1.ID)	T3
					 ON T2.ID = T1.ID
А вот ещё более нагляднее:
/*
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN dbo.fnFunc3(T1.ID)	T3 ON T3.Name != 'A2'
*/
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN  (VALUES('X'))	DUAL (X)
	OUTER APPLY dbo.fnFunc3(T1.ID)	T3 ON T3.Name != 'A2'
Была попытка добавить условия связки.
7 мар 12, 16:32    [12211216]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Crimean
Member

Откуда:
Сообщений: 13147
вроде как для

SELECT *
FROM Table1 T1
LEFT JOIN Table2 T2
CROSS APPLY dbo.fnFunc3(T1.ID) T3
ON T2.ID = T1.ID

все достаточно логично. потому как по написанию он просится для явности быть переделанным как-то так:

SELECT *
FROM Table1 T1
LEFT JOIN
( Table2 T2
CROSS APPLY dbo.fnFunc3(T1.ID) T3
) ON T2.ID = T1.ID

где внутри привнесенных () T1.ID действительно не очень определено. по идее замена LEFT JOIN >> OUTER APPLY должна решить синтаксический вопрос - тогда присутствие T1.ID внутри уже будет "законно"
7 мар 12, 17:01    [12211450]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Andrey Sribnyak
Member

Откуда: Киев
Сообщений: 600
Mnior


Мда видимо ошибка на моём реальном примере была в другом. Нагрузка сказывается.

... Но вот вариант который не работает:
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN  Table2		T2
	CROSS APPLY dbo.fnFunc3(T1.ID)	T3
					 ON T2.ID = T1.ID
Была попытка добавить условия связки.



Я понимаю... канун 8 марта... необходимость покупать подарки... и такое прочее
Только порядок операторов зачем менять?

SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN  Table2		T2
	         ON T2.ID = T1.ID
	CROSS APPLY dbo.fnFunc3(T1.ID)	T3
7 мар 12, 17:13    [12211517]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Andrey Sribnyak
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN  Table2		T2
	         ON T2.ID = T1.ID
	CROSS APPLY dbo.fnFunc3(T1.ID)	T3
Вы от смысла уходите в частности.
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN  Table2		T2
	CROSS APPLY dbo.fnFunc3(T1.ID)	T3
	         ON T2.ID = T1.ID
	          AND T3.Name != 'C2'

Если вы заметите, я в прошлом посте (12211216) привёл 3 запроса.
Это как из предложения выкинуть все кроме первого. Будъте внимательнее.
7 мар 12, 18:17    [12211963]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Andrey Sribnyak
Member

Откуда: Киев
Сообщений: 600
Mnior
Вы от смысла уходите в частности.
SELECT *
FROM Table1 T1
LEFT JOIN Table2 T2
CROSS APPLY dbo.fnFunc3(T1.ID) T3
ON T2.ID = T1.ID
>>>AND T3.Name != 'C2'<<<

[/src]
Если вы заметите, я в прошлом посте (12211216) привёл 3 запроса.
Это как из предложения выкинуть все кроме первого. Будъте внимательнее.


Ну тогда таверное как-то так:
SELECT	*
FROM	            Table1 		T1
	LEFT  JOIN  Table2		T2
	ON T2.ID = T1.ID
	CROSS APPLY dbo.fnFunc3(T1.ID)	T3
		where T3.Name !='C2'
7 мар 12, 19:24    [12212230]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Andrey Sribnyak
where T3.Name !='C2'
Ну, это уже не правильно. У вас количество строк уменьшиться. Не надо путать соединение с фильтром - это разные вещи / разный смысл.
7 мар 12, 23:02    [12213244]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Andrey Sribnyak
Member

Откуда: Киев
Сообщений: 600
Mnior,

Предиката On в cross apply нет. То, что Вам необходимо решается разворотом вашей функции в середину cross apply и там уже ограниченем через where. Ну либо вариант, что показал Crimean
8 мар 12, 16:53    [12215167]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
В книге Ицика Бен-Гана "Inside Microsoft SQL Server 2008: T-SQL Quering"
приведен алгоритм логического исполнения запроса. Из него следует,
что логически операторы соединения вычисляются слева направо.
Результатом каждого соединения является виртуальная таблица,
которая будет левым входом для следующего соединения. Но есть
хиазм-компоновка соединений (у Бен-Гана chiastic relationship). В такой
компоновке сначала перечисляются соединения, а затем условия этих
соединений. Но порядок указания этих условий строго определен: после
последнего оператора соединения задается его условие. Затем задается
условие для оператора соединения идущего следом за последним.
Последним задается условие для первого оператора соединения. Т.е.,
ВОЗМОЖНО, при такой компоновке компилятор, на логическом уровне,
начинает разбор запроса с границы между операторами соединения
(вверх) и условиями соединения (вниз) и колонки таблиц, расположенных
выше, не "видны" компилятору.
зы: критика приветствуется :)
8 мар 12, 23:23    [12216342]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Andrey Sribnyak, к этому я и веду разговор - языковая конструкция APPLY от M$ корявая по своей природе.

Мне вообще непонятно зачем ввели этот оператор APPLY. Почему связка должна стоять только в ON? Почему нельзя смешивать связи и вбухивать их хотя бы в параметры функций?
Table1 T LEFT JOIN dbo.Func2(T.Col1) F
Это я не говорю про подзапросы.
Хотя частичный ответ уже был дан (10448941). Но сейчас же нет никаких алиасов у связок.
Естественно, раньше не хватило бы мощностей на это, но сейчас ... Хотя с тех пор палец о палец не ударили. (Маркетологи и всё такое ...)

andrey odegov, вы просто описали синтаксис JOIN. Следствия. Какая нафиг критика?! (и вообще столько воды на такую ерунду)
Хотя бы описать причины возникновения / выбора такой конструкции языка у его авторов.
10724782
9 мар 12, 03:13    [12217030]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Andrey Sribnyak
Member

Откуда: Киев
Сообщений: 600
Mnior
Andrey Sribnyak, к этому я и веду разговор - языковая конструкция APPLY от M$ корявая по своей природе.

Мне вообще непонятно зачем ввели этот оператор APPLY. Почему связка должна стоять только в ON? Почему нельзя смешивать связи и вбухивать их хотя бы в параметры функций?
[src]
Table1 T LEFT >>>JOIN<<< dbo.Func2(>>>T.<<<Col1) F




Я использую APPLY когда необходимо вывести несколько первых значений из отсортированных по списку...
в JOIN - Order by вклинить не удастся а TOP тем более
9 мар 12, 14:49    [12217754]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Andrey Sribnyak, вы ошиблись топиком, мы говорим о совершенно разных вещах.
Вы о использовании текущего, а я о самом языке.
Andrey Sribnyak
в JOIN - Order by вклинить не удастся а TOP тем более
Что значит не удастся? В каком смысле?
Т.е. это противоречит теории или сходимости алгоритмов компиляции, парсирования или ещё чему нибудь?
Я лишь сказал, что вводить дополнительный оператор-понятие APPLY не вижу смысла.
Единственная проблема которая возникает если оставить JOIN и тупо расширить его функционал, лишь в том что придётся алиасы считать глобальными, т.е. они не могут повторятся в подзапросах (проблема неоднозначной трактовки).

Т.е. (для тех кто в танке):
Конструкция вида:
SELECT	*
FROM	Table1 T1
	JOIN (	SELECT	T2.*
		FROM	Table2 T2
		WHERE	T2.A > T1.B
	) T3
Будет работать как вместо JOIN написано CROSS APPLY. Логика работы видна из самих связок. Вводить дополнительное слово APPLY излишество.
Или я чего-то упустил?
11 мар 12, 01:28    [12223228]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Andrey Sribnyak
Member

Откуда: Киев
Сообщений: 600
Mnior
Т.е. (для тех кто в танке):
Конструкция вида:
SELECT	*
FROM	Table1 T1
	JOIN (	SELECT	T2.*
		FROM	Table2 T2
		WHERE	T2.A > T1.B
	) T3
Будет работать как вместо JOIN написано CROSS APPLY. Логика работы видна из самих связок. Вводить дополнительное слово APPLY излишество.
Или я чего-то упустил?



Вот когда у Вас так join заработает, то apply станет не нужным

SELECT	*
FROM	Table1 T1
	cross apply (	SELECT top 1	T2.*
		FROM	Table2 T2
		WHERE	T2.ID > T1.ID
	) T3
11 мар 12, 15:16    [12225859]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
Mnior, как быть с типами, чьи методы возвращают коллекции,
которые надо трансформировать в таблицы? Например, XML:
declare @t table(id int, x xml);
insert into @t values (1, N'<x>1</x><x>2</x><x>42</x><x>3</x>')
                    , (2, N'<x>21</x><x>22</x><x>42</x><x>23</x>');
select t.id, nc.n.value('.', 'int')
from @t t cross apply t.x.nodes('/x') nc(n);
11 мар 12, 20:43    [12228002]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
Andrey Sribnyak, совершенно неважно если ли там Top или нет.

Скорее всего APPLY нужен для маркетинга.
11 мар 12, 22:55    [12228500]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
andrey odegov
типами, чьи методы возвращают коллекции
А в чём проблема?

Тем более этот CLR и табличные типы также внедрили вместе с APPLY.
Можно придумать много вариантов синтаксиса.
Главное чтоб он был удобен и понятен.

К примеру если писать JOIN вместо APPLY, то RIGHT JOIN становится бессмысленным в данном контексте, хотя и LEFT также излишен. С другой стороны тяжело найти случаи (если они есть) когда RIGHT вообще нужен.

И вообще LEFT / RIGHT / FULL свойства скорее не JOIN, а конкретной связки. 10448941

Так, что APPLY даёт "результат" при минимуме усилий со всех сторон. Но сам по себе вещь излишняя.
Не стоит ждать вышесказанное как развитие конкретного продукта, это может быть реализовано только в новом проекте. Open-Source проекте.
11 мар 12, 23:32    [12228660]     Ответить | Цитировать Сообщить модератору
 Re: JOIN vs APPLY 5:0  [new]
andrey odegov
Member

Откуда:
Сообщений: 473
Т.е. возврат к теплым ламповым операторам?
Только выглядеть они будут по другому.
12 мар 12, 07:34    [12229144]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить