2015-06-08 2 views
1

У меня возникла проблема с запросом. Я получил 2 таблицы:несколько соединений в t-sql

declare @t1 table(pat_ref varchar(10),pas_id varchar(10), is_mnor char(1)) 
declare @t2 table (prev_pat_ref varchar(10), pat_ref varchar(10)) 

insert into @t1 
values ('1','111','y') 
     ,('5','115','y') 
     ,('6','116','y') 
     ,('2','112','n') 
     ,('3','113','y') 
     ,('4','114','n') 

insert into @t2 
values ('1','2') 
     ,('5','1') 
     ,('6','5') 
     ,('3','4') 

Теперь я хочу:

pat_ref pas_id is_mnor major_ref 
1  111  y  112 
5  115  y  112 
2  112  n  NULL 
3  113  y  114 
4  114  n  NULL 

Но, с моим запросом:

select t1.* 
, case when t1.is_mnor='y' then t3.pas_id else null end as major_ref 
from @t1 t1 
left join @t2 t2 on t1.pat_ref=t2.prev_pat_ref 
left join @t1 t3 on t3.pat_ref=t2.pat_ref 

Я получаю:

pat_ref pas_id is_mnor major_ref 
1  111  y  112 
5  115  y  111 ---this should be 112 
2  112  n  NULL 
3  113  y  114 
4  114  n  NULL 

Примечание: начальная столбцов объединения для @ t1 и @ t2: t1.pat_ref=t2.prev_pat_ref

+0

Похоже, что вы на самом деле есть 3 таблицы. Как выглядит t3? – kaz

+0

HI @kaz спасибо за ответ, на самом деле t3 является t1 как таблица псевдонимов, чтобы получить pas_id от t1. Спасибо – user3583912

+0

В вашем примере вы идете на два уровня в глубину, с 5 соединениями с 1 и 1, соединяющимися с 2, где цепь завершается. Если t2 имела строку с (2, 4), ожидаемый результат изменился бы до 114? Другими словами, вы хотите сохранить связь до конца или только до определенной глубины? –

ответ

3

Я думаю, вы хотите получить нижнее большинство отношений из t2 и связать эти строки в t1. Если это так, то вам нужно будет рекурсивное ОТВ, чтобы получить нижние большинство строк, а затем 2 присоединяется:

;with cte as(select *, prev_pat_ref as p, 1 as l from @t2 
      union all 
      select t.*, c.p, c.l + 1 
      from cte c join @t2 t on t.prev_pat_ref = c.pat_ref), 
bot as(select *, row_number() over(partition by p order by l desc) rn from cte) 

select t1.*, case when t1.is_mnor='y' then t2.pas_id else null end as major_ref 
from @t1 t1 
left join bot b on t1.pat_ref = b.p and b.rn = 1 
left join @t1 t2 on b.pat_ref = t2.pat_ref 

Fiddle http://sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/530

+0

Возможно, вы упростите запрос, чтобы не иметь объединений на внешнем уровне. –

+0

@ypercube, я должен перейти к pass_id через bot и t2, как я могу это сделать без соединения? –

+0

Привет @Giorgi Nakeuri, извините за поздний ответ. Это сработало, это то, чего я хочу. Спасибо за ответ. – user3583912

Смежные вопросы