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

Откуда:
Сообщений: 133
Всем привет!

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

- есть две таблицы T1, T2 и некоторый параметр (пусть declare @param nvarchar(50) = 'abc';).
- как реализовать такую "конструкцию":

select *
from T1
if (len(@param) > 0) inner join T2 on ....;

Т.е., если строка пустая, вернуть только T1, если нет - вернуть пересечение таблиц.
В натуре таблиц много и лабать ифы под каждое сочетание не хотелось бы...
Заранее спасибо!
16 июл 15, 09:29    [17898008]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

Откуда:
Сообщений: 133
Вот мой вариант:

select *
from T1
left join T2 on T1.Id = T2.Id and len(@param) > 0
where
(T2.Id is not null and len(@param) > 0)
or
(T2.Id is null and len(@param) = 0);

У кого короче?
16 июл 15, 09:56    [17898142]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
iap
Member

Откуда: Москва
Сообщений: 47083
SELECT *
FROM T1
LEFT JOIN T2 ON T1.ID=T2.ID AND (@param IS NULL OR @param='' OR T2.ID IS NOT NULL);
16 июл 15, 09:58    [17898155]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

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

Ваш вариант не работает
16 июл 15, 10:03    [17898189]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
iap, а как на счет поанов подобных запросов?
16 июл 15, 10:04    [17898199]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
o-o
Guest
afend,

короче будет inner join, т.к. зачем left, если потом отсеиваете T2.Id is null
16 июл 15, 10:07    [17898216]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

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

план у нас самый лучший! ))
А что тут "планить" - лефт джоин с отбором по условию?
16 июл 15, 10:08    [17898222]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

Откуда:
Сообщений: 133
o-o,

ответ неверный, т.к. в случае len(@param) = 0 он вообще
ничего не вернет, а должен вернуть всё из T1
16 июл 15, 10:09    [17898234]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
o-o
Guest
да, дошло.
но тогда ваш огород будет иметь говнопланы, вам правильно сказали.
у вас типа если передали 10 непустых параметров, будет соединение 10 таблиц(пересечение),
а если все параметры пустые, то всего 1 таблица?
вот это и есть говноплан, т.к. возможно, есть среди них есть таблица,
при соединении с к-ой вывод всего этого добра сокращается до 1 строки,
а в каких-то вариантах будет полностью первая таблица.
и для всех случаев одинаковый план, да?
это "универсальная процедура"?
16 июл 15, 10:15    [17898279]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
SELECT *
FROM T1
LEFT JOIN T2 ON T1.ID=T2.ID AND ISNULL(@param,'')<>''
16 июл 15, 10:17    [17898297]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

Откуда:
Сообщений: 133
o-o,

это отчет, поэтому разница в 5-10 секунд не критична.
Предлагайте свой вариант, я же не против.
16 июл 15, 10:22    [17898339]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
iap
Member

Откуда: Москва
Сообщений: 47083
Cygapb-007
SELECT *
FROM T1
LEFT JOIN T2 ON T1.ID=T2.ID AND ISNULL(@param,'')<>''
Нужет-то INNER JOIN, если ISNULL(@param,'')<>''
Значит, там не должно быть T2.ID IS NULL
16 июл 15, 10:25    [17898355]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

Откуда:
Сообщений: 133
Cygapb-007,

не-е, не работает. Обращаю Ваше внимание, что @param либо '', либо 'abc' - не null!
16 июл 15, 10:26    [17898364]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
StarikNavy
Member

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

select *
from T1
where
@param is null 
union all
select *
from T1 inner join T2 ...
where
@param is not null 


?
16 июл 15, 10:31    [17898403]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

Откуда:
Сообщений: 133
StarikNavy
afend,

select *
from T1
where
@param is null 
union all
select *
from T1 inner join T2 ...
where
@param is not null 


?


извините, недопонял... @param - это строка, пустая или с символами, не null
16 июл 15, 10:35    [17898422]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
o-o
Guest
а тогда по мне так проще и лучше собрать динамику.
в таком духе:
declare @p2 int = 1 /*null*/, 
        @p3 int = 1 /*null*/,
        @p4 int = 1 /*null*/;

declare @sql varchar(4000) = 'select * from t1';
if @p2 is not null set @sql =  @sql + ' join t2 on t1.id = t2.id';
if @p3 is not null set @sql =  @sql + ' join t3 on t1.id = t3.id';
if @p4 is not null set @sql =  @sql + ' join t4 on t1.id = t4.id';

print @sql;

писанины ничуть не больше, план тоже будет нужный
16 июл 15, 10:42    [17898456]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

Откуда:
Сообщений: 133
o-o,

ну, тоже вариант...
16 июл 15, 10:47    [17898475]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
StarikNavy
Member

Откуда: Москва
Сообщений: 2407
afend

извините, недопонял... @param - это строка, пустая или с символами, не null

ну замените is null на (len(@param) > 0
16 июл 15, 11:11    [17898563]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
Ну да. Тут Только динамика.
Планы будут под каждую ситуацию свои, и закешенные (правда не долго).
16 июл 15, 11:12    [17898568]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
o-o
Guest
StarikNavy,

только параметров у него может быть 10 и в соединение, например,
должны попасть таблицы: исходная, 5, 7 и 9.
как будет выглядеть условие для каждого участника юниона?
16 июл 15, 11:14    [17898576]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
o-o
Guest
Mike_za
Ну да. Тут Только динамика.
Планы будут под каждую ситуацию свои, и закешенные (правда не долго).

очень даже надолго.
в отчетных системах чем больше рекомпилируешь, тем всем только лучше.
у нас с вами противоположные приоритеты, DWH не страдает от частых рекомпиляций.
на выборку туча времени уходит.
16 июл 15, 11:18    [17898590]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
Mike_za
Member

Откуда: Москва
Сообщений: 1176
o-o, так можно сразу опцию with recompile тогда азводить?
16 июл 15, 11:19    [17898596]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
o-o
Guest
можно и заводить.
хотя некоторые отчеты строят прямо поверху OLTP
это настоящий подарок всем.
причем при дедлоке обычно откатывают отчетников.
и вот тогда можно побольше recompile понаписать, чтобы побыстрее отказались от этой идеи
и вынесли DWH на другой сервер
16 июл 15, 11:30    [17898647]     Ответить | Цитировать Сообщить модератору
 Re: inner join по условию  [new]
afend
Member

Откуда:
Сообщений: 133
Всем участвовавшим спасибо за обсуждение!
16 июл 15, 11:46    [17898717]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить