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

Откуда:
Сообщений: 238
Добрый день
не могу понять в чем проблема:
имеется таблица provodka в которой хранятся операции по счетам( для каждого счета). идентификатор операции id_Op - в таблице встречается два раза(один раз по Дт и один раз по Кт), идентификатор Дт/Кт - tip(1/0).
Собираю в единый документ-проводку запросом
select 
d.id_Op, 
d.Chet, 
k.Chet 
from 
provodka d inner join provodka k on d.id_Op = k.id_Op
where 
d.tip = 1 and k.tip = 0 and
(d.Chet = '20202' or k.Chet = '20202')


при запуске запроса все зависает. Если делать условие только по Дт или только по Кт то работает молниеносно. Можно обойти конечно через union select, но это как-то некрасиво.

Что же все-таки не так я делаю?

MS Sql Server 9.0.5, в таблице записей более 65 млн.
21 мар 14, 12:05    [15765166]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Стреляю на вскидку - проблема в OR. В нем слабость оптимизатора :) Изменить запрос, скажем, на UNION ALL вариант.
21 мар 14, 12:28    [15765401]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
iap
Member

Откуда: Москва
Сообщений: 47001
Владислав Колосов
Стреляю на вскидку - проблема в OR. В нем слабость оптимизатора :) Изменить запрос, скажем, на UNION ALL вариант.
trexmernii
но это как-то некрасиво
21 мар 14, 12:31    [15765424]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
Konst_One
Member

Откуда:
Сообщений: 11540
вы бы хоть посмотрели актуальный план своего запроса для начала, может там индексов будет достаточно добавить/изменить
21 мар 14, 12:32    [15765443]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7868
Автору шашечки или ехать?
21 мар 14, 13:13    [15765855]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
invm
Member

Откуда: Москва
Сообщений: 9413
select 
d.id_Op, 
d.Chet, 
k.Chet 
from 
provodka d inner join provodka k on d.id_Op = k.id_Op and k.tip = 0 and k.Chet = '20202'
where 
d.tip = 1 and d.Chet = '20202';
?
21 мар 14, 13:15    [15765877]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
trexmernii
Member

Откуда:
Сообщений: 238
Konst_One
вы бы хоть посмотрели актуальный план своего запроса для начала, может там индексов будет достаточно добавить/изменить

к сожалению план посмотреть не могу - нет доступа.

invm
select 
d.id_Op, 
d.Chet, 
k.Chet 
from 
provodka d inner join provodka k on d.id_Op = k.id_Op and k.tip = 0 and k.Chet = '20202'
where 
d.tip = 1 and d.Chet = '20202';
?

Запрос ничего не возвращает
21 мар 14, 13:39    [15766104]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
Konst_One
Member

Откуда:
Сообщений: 11540
скрипт таблицы с индексами тогда сюда выложите, может что и придумает народ
21 мар 14, 13:45    [15766179]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
trexmernii
Можно обойти конечно через union select, но это как-то некрасиво.
Ну замените на тучу CASE-ов - и будет ещё более некрасиво.
SELECT	L.id_Op
,	L.Chet
,	R.Chet
,	L.tip
FROM	dbo.provodka	L
JOIN	dbo.provodka	R ON R.id_Op	 = L.id_Op
			 AND R.tip	!= L.tip
--CROSS APPLY (SELECT L.* WHERE L.tip = 0 UNION ALL SELECT R.* WHERE L.tip = 1) D
--CROSS APPLY (SELECT R.* WHERE L.tip = 0 UNION ALL SELECT L.* WHERE L.tip = 1) K
WHERE	L.Chet = '20202'

Далее через CROSS APPLY + UNION ALL или куча CASE-ов

APPLY - такая же необходимая вещь как и пробелы.
21 мар 14, 14:25    [15766674]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
trexmernii
Member

Откуда:
Сообщений: 238
Все же пришлось через Union - но работает, так как надо.
Select * From (
Select *, Chet as Chet_1 from provodka where tip = 0 
Union 
Select *, Chet as Chet_1 from provodka where tip = 1 
) as a 
where a.Chet_1 = '20202'
21 мар 14, 15:45    [15767456]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
trexmernii
Все же пришлось через Union - но работает, так как надо.
Вообще-то нет, варант APPLY + UNION работает в один скан, а у вас в два.
22 мар 14, 01:20    [15769926]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
trexmernii
Member

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

Спасибо! Действительно - Ваш вариант замечательно работает!
24 мар 14, 19:24    [15779771]     Ответить | Цитировать Сообщить модератору
 Re: Соединить таблицу саму с собой  [new]
west74
Member

Откуда: Челябинск
Сообщений: 76
а обединять таблицу из 65 мил строк действительно надо ?
может покопать в сторону group by:



declare @provodka table (id_op int,Chet varchar(20),tip int,summa numeric(10,2))

insert into @provodka (id_op ,Chet,tip,summa ) values
(1,'20202',0,2000),
(1,'20202',1,1000),
(1,'20202',2,3000),
(2,'20202',0,4000),
(3,'20202',1,700);

select
d.id_Op,
d.Chet,
sum(case when d.tip=0 then d.summa else 0 end) summa0,
sum(case when d.tip=1 then d.summa else 0 end) summa1

from
@provodka d
where d.tip in (0,1) and d.Chet = '20202'
group by d.id_Op,d.Chet
having sum(case
when d.tip=0 then 1
when d.tip=1 then 2 end) =3
25 мар 14, 09:39    [15781523]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить