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

Откуда: Стерлитамак - Москва
Сообщений: 1023
Есть запрос в таком духе:
select *
from table1
inner join table2 on table1.id1 = table2.id_table1
inner join table3 on table1.id2 = table3.id_table1

При определенных условиях нужно чтобы не срабатывала первая сцепка. Т.е. вообще исключить ее. Чтобы запрос выполнялся в таком виде:

select *
from table1
inner join table3 on table1.id2 = table3.id_table1

Можно ли как то сделать это без использования динамического SQL?

- запрос с переменным числом параметров не подходит, нужно именно "отключить" сцепку
- LEFT JOIN тоже не прокатит т.к. table1 огромна, а нужно быстро :)
23 ноя 11, 12:19    [11643310]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2392
Блог
select *
from table1
inner join table2 on (table1.id1 = table2.id_table1 or (your-condition))
inner join table3 on table1.id2 = table3.id_table1
??
23 ноя 11, 12:24    [11643366]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
чтоб побыстрее
select ... 
inner join ...
inner join ...
where <условие для двух джойнов>
union all
select ... 
inner join ...
where <условие для одного джойна>
23 ноя 11, 12:27    [11643398]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
Klick, а че делать если table2 пустая? Вообще-то сделать нечто подобное можно, но врядли в общем случае. Скорее всего тока частное решение. Это если для одного запроса. Но что вам мешает их сделать пару штук? Или через UNION?
23 ноя 11, 12:28    [11643414]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Klick
Member

Откуда: Стерлитамак - Москва
Сообщений: 1023
kDnZP
Klick, а че делать если table2 пустая? Вообще-то сделать нечто подобное можно, но врядли в общем случае. Скорее всего тока частное решение. Это если для одного запроса. Но что вам мешает их сделать пару штук? Или через UNION?


Вот как раз таки соль в том что table2 может быть пустой... сорри забыл сразу написать... вот тада грабельки...
Пару штук сделать копи-пастой не проблема, но хотелось красиво, да и запрос в реальности немаленький... если что-то менять потом придется оба переписывать...
23 ноя 11, 12:42    [11643556]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Klick, чтоб не писать два раза, часть запроса с одним джойном, который присутствует в обоих случаях, можно вынести в cte
23 ноя 11, 12:46    [11643591]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Klick
Member

Откуда: Стерлитамак - Москва
Сообщений: 1023
Универсального решения вроде как нет. Но Павел Воронцов вернул меня к моим вчерашним экспериментам, я тоже так пытался:
inner join table2 on (table1.id1 = table2.id_table1 or (your-condition))
Единственной проблемой была пустая table2. Решил ее вставляя туда одну запись с нулевыми id. Получается что-то вроде cross join большой таблицы с таблицей с одной записью.
Щас проверю время выполнения...
23 ноя 11, 12:54    [11643670]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
Shakill
Klick, чтоб не писать два раза, часть запроса с одним джойном, который присутствует в обоих случаях, можно вынести в cte

+1
Либо вспомогательную вьюху сделать, если версия сервака старая.
23 ноя 11, 12:55    [11643680]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Паганель
Member

Откуда: Винница
Сообщений: 22550
Klick
без использования динамического SQL?
постройка запроса клиентом считается?
23 ноя 11, 12:57    [11643711]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Klick
Member

Откуда: Стерлитамак - Москва
Сообщений: 1023
Shakill
часть запроса с одним джойном, который присутствует в обоих случаях, можно вынести в cte


А можно простенький пример? Не соображу как
23 ноя 11, 12:57    [11643717]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Klick
Member

Откуда: Стерлитамак - Москва
Сообщений: 1023
Паганель
постройка запроса клиентом считается?


Неа :) Как раз переписывается именно этот вариант. На клиенте строился текст запроса. Переделал все на параметры, запихал в храниму, осталось самая малость, вот это извращение :)
23 ноя 11, 12:59    [11643740]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Shakill
Member

Откуда: мск
Сообщений: 1887
Klick
Shakill
часть запроса с одним джойном, который присутствует в обоих случаях, можно вынести в cte

А можно простенький пример? Не соображу как

простенький пример есть в документации http://msdn.microsoft.com/ru-ru/library/ms190766.aspx
23 ноя 11, 13:10    [11643853]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
Павел Воронцов
select *
from table1
inner join table2 on (table1.id1 = table2.id_table1 or (your-condition))
inner join table3 on table1.id2 = table3.id_table1
??
declare @JoinOff bit=0;
select table1.*,table2.*
from table1
left join table2 on table1.id1 = table2.id_table1 and @JoinOff=0
join table3 on table1.id2 = table3.id_table1;
23 ноя 11, 13:16    [11643905]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
SomewhereSomehow
Member

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

Хм...интересно как оно выглядит в реальном запросе? А именно, у вас вторая связка, она чисто ограничивающая множество. Т.е. никаких полей из table2 вам не надобно? Если так, то можно перенести это в условие where в exists, где либо проверять значение параметра, либо истинность exists. Если же из второй таблица так же беруться какие-то поля, то возникает вопрос. Когда мы ее исключим - изменится число колонок результирующего селекта или нет? Если да, то имхо, разные ветки кода самое правильное.

Если нет, то что выводить в тех колонках, которые берутся из таблицы2 когда ее нет? Допустим ничего, тогда наверное все-таки вариант с left join зря вы отмели. Проверяйте там ваше условие и все, исчезнет проблема с "пустой таблицей".

Еще, если кол-во строк не шибко большое после джойна таблицы 1 и 3, то можно разбить запрос на два запроса. В первый вынести только джоин таблиц 1 и 3 и все соотв.условия, результат записать в табличную переменную или временную таблицу, а дале в зависисмости от проверки параметра делать либо просто выборку из временной таблицы, либо выборку из временной + таблица2.
Ну либо как посоветовали cte + union all, но тогда не скажу какая будет производительность.
23 ноя 11, 13:17    [11643920]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
iap
Member

Откуда: Москва
Сообщений: 47142
iap
declare @JoinOff bit=0;
select table1.*,table2.*
from table1
left join table2 on table1.id1 = table2.id_table1 and @JoinOff=0
join table3 on table1.id2 = table3.id_table1;
declare @JoinOff bit=0;
select table1.*,table3.*
from table1
left join table2 on table1.id1 = table2.id_table1 and @JoinOff=0
join table3 on table1.id2 = table3.id_table1;
23 ноя 11, 13:17    [11643924]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2392
Блог
select *
from table1
inner join table3 on table1.id2 = table3.id_table1
where table1.id1 in (select min(isnull(table2.id_table1,table1.id1)) as id from table2 right join (select 0 as id) a on 1=1)
23 ноя 11, 13:18    [11643932]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2392
Блог
select *
from table1
inner join table3 on table1.id2 = table3.id_table1
where table1.id1 in (select isnull(table2.id_table1,table1.id1) as id from table2 right join (select 0 as id) a on 1=1)
то есть.
23 ноя 11, 13:20    [11643958]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Klick
Member

Откуда: Стерлитамак - Москва
Сообщений: 1023
SomewhereSomehow
А именно, у вас вторая связка, она чисто ограничивающая множество. Т.е. никаких полей из table2 вам не надобно?

Именно так. Там некие фильтры проживают :)

SomewhereSomehow
Еще, если кол-во строк не шибко большое после джойна таблицы 1 и 3, то можно разбить запрос на два запроса.


Шибко большое :( table1 это таблица движений товаров по складам...

Я сделал так (@ВДвижении табличная переменная = table2):

inner join @ВДвижении ВДвижении on (@SelectAll=1 or (ТаблицаОстатки.Ресурс = ВДвижении.Ресурс and ТаблицаОстатки.Склад = ВДвижении.Склад))

и получил грабли от оптимизатора :( Если вместо @SelectAll нарисовать 0, то все летает, а если переменная то приехали :(
23 ноя 11, 13:28    [11644021]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2392
Блог
Как вариант
select *
from table1
inner join (select isnull(table2.id_table1,a.id) as id, table2.* from table2 right join (select 0 as id) a on 1=1) b on b.id in (table1.id1,0)
inner join table3 on table1.id2 = table3.id_table1
если table2 где-то еще фигурирует
23 ноя 11, 13:28    [11644025]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Klick
Именно так. Там некие фильтры проживают :)
Ну так и перенесите ее в where в exists, глядишь и побыстрее станет?

Klick
inner join @ВДвижении ВДвижении on (@SelectAll=1 or (ТаблицаОстатки.Ресурс = ВДвижении.Ресурс and ТаблицаОстатки.Склад = ВДвижении.Склад))
и получил грабли от оптимизатора :( Если вместо @SelectAll нарисовать 0, то все летает, а если переменная то приехали :(

Так все-таки там inner? потому как если inner понятно почему все летает, потмоу что если 1=0 то никогда никаких записей вообще не вернется...
23 ноя 11, 13:51    [11644258]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Klick
Member

Откуда: Стерлитамак - Москва
Сообщений: 1023
Если 0=1 тогда работает сцепка.
Если 1=1 тогда она не работает.
Все замечательно пока не пишу @SelectAll=1
Умирает все безнадежно :(
23 ноя 11, 14:59    [11645050]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
declare @JoinOff bit=0;
select table1.*,table2.*
from table1
inner  join( select * from  table2  where 1 =@JoinOff) x on table1.id1 = isnull(x.id_table ,table1.id1)
join table3 on table1.id2 = table3.id_table1;
23 ноя 11, 15:06    [11645126]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
SomewhereSomehow
Member

Откуда: Moscow
Сообщений: 2480
Блог
Klick
Если 0=1 тогда работает сцепка.
Если 1=1 тогда она не работает.
Все замечательно пока не пишу @SelectAll=1
Умирает все безнадежно :(

Ах у вас там в джойне OR вкорячено! Ну тогда ситуация обратная, вместо ни одной записи - будут все.
declare @t1 table (a int);
declare @t2 table (a int);
insert into @t1 select 1 union all select 2;
insert into @t2 select 1 union all select 2;
select * from @t1 t1 join @t2 t2 on 1=0 or t1.a = t2.a;
select * from @t1 t1 join @t2 t2 on 1=1 or t1.a = t2.a; -- это ок что здесь результат как у кросс джойна??
select * from @t1 t1 cross join @t2 t2;
Если это ок, то я тогда я вообще не понял задачу...
23 ноя 11, 15:27    [11645368]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
Klick
Member

Откуда: Стерлитамак - Москва
Сообщений: 1023
Если результат как у кросс джойна это ок :) В этом варианте в table2 всего одна "фиктивная" запись... Вроде в виду кросс джойн, но выдает как раз все записи из table1. То что надо :)
Проблема теперь осталась в параметре :(
23 ноя 11, 15:41    [11645529]     Ответить | Цитировать Сообщить модератору
 Re: Исключить отключить INNER JOIN  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
Klick, на что народ тока не пойдет, лишь бы UNION ALL не писать.
23 ноя 11, 15:52    [11645664]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить