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

Откуда:
Сообщений: 20
Всем привет.
Помогите составить запрос.

есть Table1 a - a.Parent, a.Child, получена путем тяжелого xml запроса.
есть Table2 b - b.Parent, b.Child

На каждую пару из Table2 должно быть две пары в Table1 в следующем виде:
прямая пара "Parent->Child" и обратная "Child->Parent"

Например.
Если в Table2 есть пара
guid1 guid2

то в Table1 должно быть две пары
guid1 guid2
guid2 guid1

Бьюсь над запросом который мне выдаст все пары из Table2, которых нету в Table1.
Пробую двойной Right join, двойной not exists - всё без толку.

запрос с double not exist - уходит в себя, ждал 3 часа.
select 
   b.Parent, b.Child
from Table2 b
where
  (not exists ( select * from Table1 a where a.Parent = b.Parent and a.Child = b.Child ))
or 
  (not exists ( select * from Table1 a where a.Parent = b.Child and a.Child = b.Parent ))


запрос с right join, я ухожу в глубокий депресняк когда пытаюсь добавить второй right join.
;with xml as 
(
  select 
   a.Parent
   b.Child
 from Table1 a
)
 select 
  b.Parent
  b.Child
 from xml x 
 right outer join Table2 b1 on x.Parent=b1.Parent and x.Child=b1.Child
where x.Parent is null


с одним rjoin даже валидные данные возвращаются, но только половина.
для олучения второй половину пытаюсь добавить еще один, тут же пропадают данные от первого rjoin - возвращаются все null.
и непонятно что приходит от второго rjoin

with xml as 
(
  select 
   a.Parent
   b.Child
 from Table1 a
)
 select 
  b.Parent
  b.Child
 from xml x 
 right outer join Table2 b1 on x.Parent=b1.Parent and x.Child=b1.Child
 right outer join Table2 b2 on x.Parent=b2.Child and x.Child=b2.Parent
where x.Parent is null



нужна помощь.
22 июл 14, 14:19    [16341159]     Ответить | Цитировать Сообщить модератору
 Re: двойной Not exists на multiple colums  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Непонятно, что нужно.
Можно увидеть все комбинации пар?
22 июл 14, 14:43    [16341354]     Ответить | Цитировать Сообщить модератору
 Re: двойной Not exists на multiple colums  [new]
_human
Member

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

например, если ничего не напутал.. лучше когда есть данные
; with table1 as 
(select * from ( values ('guid1', 'guid2') ) q (parent, childid) )
, table2 as (select * from ( values ('guid1', 'guid2'), ('guid2', 'guid1'), ('guid3', 'guid4'), ('guid4', 'guid3') ) q (parent, childid) )

select * from table2 t2
where not exists (select * from table1 t1 where t2.parent = t1.parent or t2.parent = t1.childid) 
22 июл 14, 15:14    [16341604]     Ответить | Цитировать Сообщить модератору
 Re: двойной Not exists на multiple colums  [new]
Glamorama
Member

Откуда:
Сообщений: 152
Вероятно, что у Вас просто индекса подходящего нет, а размеры Table1/Table2 довольно приличные.
Можно так попробовать:
select 
    a.Parent
  , a.Child
from Table2 a
--"прямая" пара
left join Table1 b
   on b.Parent = a.Parent
  and b.Child = a.Child
-- "обратная" пара
left join Table1 c
   on c.Parent = a.Child
  and c.Child = a.Parent
group by 
    a.Parent
  , a.Child
having 
         -- не нашли "прямую" пару
         sum( case when b.Parent is not null then 1 else 0 end ) = 0 
         -- или не нашли "обратную"
   or sum( case when c.Parent is not null then 1 else 0 end ) = 0
22 июл 14, 15:19    [16341638]     Ответить | Цитировать Сообщить модератору
 Re: двойной Not exists на multiple colums  [new]
aleks2
Guest
Умора.

select Parent, Child 
  from (
         select Parent, Child from Table2
         union all
         select Child, Parent from Table2
        ) as X
except
select Parent, Child from Table1
22 июл 14, 15:37    [16341784]     Ответить | Цитировать Сообщить модератору
 Re: двойной Not exists на multiple colums  [new]
PaulD_
Member

Откуда:
Сообщений: 20
Glamorama,
боюсь что Left join тоже уйдёт в себя как и not exists, я поэтому пробую right join использовать.
Т.е. сначала with с тяжелым xml, а потом right join на него.
Но идея с group by having интересная, сейчас попробую.

Индексы на таблицах только основные на PK. там где xml колонка, одельного индекса на xml нету.
Кол-во пар в Table2 ~5млн, соответвенно в Table1 ~10млн. Один right join из моего примера выдает 91т. запсей, время выполнения запроса ~5м. Вот тут я пробовал добавить xml index (sql 2008r2) и частичный Xml index. SQL plan показывает исользование новых xml индексов, но выигрыш по времени секунд 20 всего. А размер индексов 6x от размера базы получался, где-то +50GB. Удалил я их, не стоят они 20 секунд выигрыша.


Я старался описать что и как поподробнее, но сам как начинаю читать своё описание уже путаюсь. Накидаю пример данных чуть попозже.
22 июл 14, 15:44    [16341849]     Ответить | Цитировать Сообщить модератору
 Re: двойной Not exists на multiple colums  [new]
PaulD_
Member

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

Вам это семечки, а мне человеку далекому от SQL нервные клеткие :)
22 июл 14, 15:48    [16341884]     Ответить | Цитировать Сообщить модератору
 Re: двойной Not exists на multiple colums  [new]
PaulD_
Member

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

ваш запрос похоже то что надо.
только один нюанс, результат возвращает также и перевернутые пары и нету зацепок восстановить порядок.
кстати, запрос отработал довольно шустро за 3m:50s

Можно ли как-то разбить, но так чтобы except выполнялся один раз? Напомню, что это тяжелый xml запрос, и занимает 90% времени.

select Parent, Child 
  from (
         select Parent, Child from Table2
        ) as X1
except
select Parent, Child from Table1
union all
select Parent, Child 
  from (
         select Child, Parent from Table2
        ) as X2
except
select Parent, Child from Table1
22 июл 14, 16:17    [16342137]     Ответить | Цитировать Сообщить модератору
 Re: двойной Not exists на multiple colums  [new]
aleks2
Guest
PaulD_
aleks2,

ваш запрос похоже то что надо.
только один нюанс, результат возвращает также и перевернутые пары и нету зацепок восстановить порядок.
[/src]


Ужос!
select t2.Parent, t2.Child 
from Table2 t2 inner join
(select Parent, Child 
  from (
         select Parent, Child from Table2
        ) as X1
except
select Parent, Child from Table1
union all
select Parent, Child 
  from (
         select Child, Parent from Table2
        ) as X2
except
select Parent, Child from Table1
) as X on t1.Parent=x.Parent and t2.Child = x.Child
22 июл 14, 16:34    [16342252]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить