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

Откуда: Саратов
Сообщений: 778
Товарищи, помогите устранить пробел в знании T-SQL синтаксиса.
Задача выражается следующим кодом.
select coalesce(tf.ID, tf2.ID) as ID,  coalesce(tf.value, tf2.value) as value
 from SomeTableFunction(1) tf
outer apply 
(select * from SomeTableFunction(2)  where tf.ID is null /*если нет, то берем с другим аргументом*/) tf2

-- То есть логика такая - вывести значение некой таблично функции, если она ничего не выводит, то вывести значение это же функции с другим аргументом. Но - при таком синтаксисе эта логика не работает, если tf ничего не выводит, то и в результирующи набор ничего не попадет.
То есть "outer apply" нужно заменить на какой то иной оператор соединения, наподобие Full Outer Join.
Как?
4 июл 13, 14:20    [14522365]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
select tf.ID as ID,  tf.value as value
 from SomeTableFunction(1) tf
union all
select tf.ID as ID,  tf.value as value
 from SomeTableFunction(2) tf
where not exists(select 1 from  SomeTableFunction(1) )
4 июл 13, 14:26    [14522409]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
А где связь между tf и tf2?
4 июл 13, 14:27    [14522417]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
McCar
Member

Откуда: Саратов
Сообщений: 778
Мистер Хенки
select tf.ID as ID,  tf.value as value
 from SomeTableFunction(1) tf
union all
select tf.ID as ID,  tf.value as value
 from SomeTableFunction(2) tf
where not exists(select 1 from  SomeTableFunction(1) )

А при таком синтаксисе SomeTableFunction(1) будет вызываться один раз или два?
4 июл 13, 14:37    [14522513]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
McCar,
два.
Еще можно через таблицу сделать
insert into @t (id,value)
select tf.ID as ID,  tf.value as value

 from SomeTableFunction(1) tf
if @@rowcount=0
insert into @t(id,value)
select tf.ID as ID,  tf.value as value
 from SomeTableFunction(2) tf
4 июл 13, 15:03    [14522760]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
Может, так?
SELECT ID=ISNULL(F1.ID,F2.ID),value=CASE WHEN F1.ID IS NULL THEN F2.value ELSE F1.value END
FROM SomeTableFunction(1) F1 FULL JOIN SomeTableFunction(2) F2 ON F1.ID=F2.ID;
4 июл 13, 15:05    [14522774]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
McCar
Member

Откуда: Саратов
Сообщений: 778
Мистер Хенки
McCar,
два.
Еще можно через таблицу сделать
insert into @t (id,value)
select tf.ID as ID,  tf.value as value

 from SomeTableFunction(1) tf
if @@rowcount=0
insert into @t(id,value)
select tf.ID as ID,  tf.value as value
 from SomeTableFunction(2) tf

Не.. Multi-statement функции для меня не вариант, мне для олапной таблицы фактов, там производительность критична.
4 июл 13, 15:13    [14522823]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
RubinDm
Member

Откуда:
Сообщений: 461
McCar
Мистер Хенки
McCar,два.Еще можно через таблицу сделать
Не.. Multi-statement функции для меня не вариант, мне для олапной таблицы фактов, там производительность критична.
иногда инлайны в план вписываются даже хуже, чем мульти-статменты.
4 июл 13, 15:22    [14522898]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
McCar
Member

Откуда: Саратов
Сообщений: 778
iap
Может, так?
SELECT ID=ISNULL(F1.ID,F2.ID),value=CASE WHEN F1.ID IS NULL THEN F2.value ELSE F1.value END
FROM SomeTableFunction(1) F1 FULL JOIN SomeTableFunction(2) F2 ON F1.ID=F2.ID;

Тут не понял логику соединения "ON F1.ID=F2.ID".
Это условие никогда не выполнится.
А даже если выполнится, если одни из наборов пусто, результирующий тоже будет пустой
4 июл 13, 15:22    [14522900]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
McCar
iap
Может, так?
SELECT ID=ISNULL(F1.ID,F2.ID),value=CASE WHEN F1.ID IS NULL THEN F2.value ELSE F1.value END
FROM SomeTableFunction(1) F1 FULL JOIN SomeTableFunction(2) F2 ON F1.ID=F2.ID;


Тут не понял логику соединения "ON F1.ID=F2.ID".
Это условие никогда не выполнится.
А даже если выполнится, если одни из наборов пусто, результирующий тоже будет пустой
Как Вы представляете себе FULL JOIN?
4 июл 13, 15:29    [14522961]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
McCar
Member

Откуда: Саратов
Сообщений: 778
iap
McCar
пропущено...

Тут не понял логику соединения "ON F1.ID=F2.ID".
Это условие никогда не выполнится.
А даже если выполнится, если одни из наборов пусто, результирующий тоже будет пустой
Как Вы представляете себе FULL JOIN?

Ой...
Таки да.. загнался. :-)
4 июл 13, 15:39    [14523048]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
McCar
Member

Откуда: Саратов
Сообщений: 778
iap
Может, так?
SELECT ID=ISNULL(F1.ID,F2.ID),value=CASE WHEN F1.ID IS NULL THEN F2.value ELSE F1.value END
FROM SomeTableFunction(1) F1 FULL JOIN SomeTableFunction(2) F2 ON F1.ID=F2.ID;

А так получается что функция в любом случае вызывается два раза.
Мне же нужно, чтобы с аргрументом =2 она вызывалась только в тех случаях, когда нет результатат для аргумента=1
4 июл 13, 15:45    [14523098]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
RubinDm
Member

Откуда:
Сообщений: 461
use [tempdb]
go

create function dbo.someFunc(@argv int)
-- функция возвращает что-то только для значений @argv,
-- которые заведомо делятся нацело только на 3 (три).
returns table as return

select X.ID
from
( select ID = @argv * 10 + 1
  union all
  select ID = @argv * 10 + 2
  union all
  select ID = @argv * 10 + 3
) X
where @argv % 3 = 0
go

--select * from dbo.someFunc(1)
--select * from dbo.someFunc(2)
--select * from dbo.someFunc(3)
--select * from dbo.someFunc(4)
--select * from dbo.someFunc(5)
--select * from dbo.someFunc(6)
--select * from dbo.someFunc(7)
--select * from dbo.someFunc(8)

select top (1) with ties Func.[ID] -- , Func.AndOtherFields
from
( select argv = 1   union all
  select argv = 2   union all
  select argv = 3   union all
  select argv = 4   union all
  select argv = 5   union all
  select argv = 6   union all
  select argv = 7   union all
  select argv = 8
) args -- это возможные аргументы на входе
cross apply -- применяем args.argv к TFn
( select F.[ID] -- , F.AndOtherFields
  from dbo.someFunc(args.argv) F
) Func
order by args.argv asc -- сортируем по значению аргумента

drop function dbo.someFunc
go
4 июл 13, 15:51    [14523158]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
McCar
Мне нужно, чтобы с аргрументом =2 она вызывалась только в тех случаях, когда нет результатат для аргумента=1

Вызвали функцию с аргументом 1, она вернула таблицу (id, <value/null>), отобрали все ID для которых value is null. Вопрос - как передать в ту же самую функцию отобранные ID, если она их не требует при вызове (даже с аргументом 2)?
4 июл 13, 16:04    [14523253]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
McCar
Мистер Хенки
McCar,
два.
Еще можно через таблицу сделать
insert into @t (id,value)
select tf.ID as ID,  tf.value as value

 from SomeTableFunction(1) tf
if @@rowcount=0
insert into @t(id,value)
select tf.ID as ID,  tf.value as value
 from SomeTableFunction(2) tf

Не.. Multi-statement функции для меня не вариант, мне для олапной таблицы фактов, там производительность критична.

получается выбор между multi-statement или дополнительным вызовом SomeTableFunction(). надо сравнивать
4 июл 13, 16:13    [14523306]     Ответить | Цитировать Сообщить модератору
 Re: Аналог Full Outer Join для соединения табличных функций  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6724
RubinDm
иногда инлайны в план вписываются даже хуже, чем мульти-статменты.
Ага, ага, прям таки это тот случай.
4 июл 13, 16:49    [14523571]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить