Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 посчитать 3 суммы оптимально  [new]
beg_inner
Guest
нужно посчитать 3 суммы из 3 разных таблиц (Tab_C, Tab_R, Tab_Rec)
для всех id из главной таблицы Tab_P, удовлетворяющих условиям:
where dataoffman is not null 
  and  dataricman is not null

вот такой код работает правильно:

with t as(
SELECT     
		P.ID_B, 
		P.cod,
		(select SUM(  ISNULL(C.val_C,0) ) from tab_C C where C.id = P.id) AS val_C,
		(select SUM(ISNULL(R.val_R,0)) from tab_R AS R where R.id = P.id) AS val_R,
		(select SUM(isnull(Rec.val_Rec,0)) from  tab_Rec Rec where Rec.id = P.id) AS val_Rec
								
FROM    tab_P AS P
             
where P.dataoffman is not null 
  and P.dataricman is not null
  )
  
select ID_B, 
	   cod,
		isnull(SUM(val_C), 0) AS val_C,
		isnull(SUM(val_R), 0) AS val_R,
		isnull(SUM(val_Rec), 0) AS val_Rec
from t
group by ID_B, 
		 cod
		

но это все равно что отдельно посчитать каждую сумму по каждой таблице и потом прилепить к главной.
пробовала посчитать все в одном селекте, пpисоединив 3 таблицы к главной по left join,
но считает неправильно, потому что так строки задваиваются и затраиваются.
но почему-то кажется, что как-то можно сделать, вычитав главную таблицу 1 раз.
помогите пожалуйста
4 апр 12, 18:36    [12366654]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
beg_inner, UNION ALL знаете?
4 апр 12, 18:49    [12366746]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
qwerty112
Guest
select P.id, c1.xz, r1.xz, ...

FROM     P
left join
(select C.id, SUM(ISNULL(C.val_C,0)  as xz from C group by C.id) c1
  on P.id=c1.id
left join
(select R.id, SUM(ISNULL(R.val_R,0)  as xz from R group by R.id) r1
  on P.id=r1.id
left join
...             
4 апр 12, 19:00    [12366806]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
beg_inner
Guest
kDnZP,

да, знаю.
но хоть убейте, не вижу, куда его приделать.
может, объяснила плохо?
3 столбца с суммами считаются, каждый по отдельной таблице (но в соединении с основной таблицей).
4 апр 12, 19:00    [12366807]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
beg_inner
Guest
qwerty112,

о, вот это похоже оно.
я вместо "каждому свой group by" написала один общий для всех, после всех left join-ов.
и это было неправильно.
сейчас попробую Ваш вариант
4 апр 12, 19:03    [12366825]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
beg_inner
Guest
qwerty112
select P.id, c1.xz, r1.xz, ...

FROM     P
left join
(select C.id, SUM(ISNULL(C.val_C,0)  as xz from C group by C.id) c1
  on P.id=c1.id
left join
(select R.id, SUM(ISNULL(R.val_R,0)  as xz from R group by R.id) r1
  on P.id=r1.id
left join
...             


нет, не проходит, т.к. требует поместить все xz в group by
4 апр 12, 19:14    [12366884]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
kDnZP
Member [заблокирован]

Откуда: ★[msg=16399436]★[msg=20850760]
Сообщений: 11289
beg_inner, э... ну тогда про OUTER APPLY слышали?

Мне просто интересно сам смысл... Почему вы считаете что LEFT JOIN будет быстрее? Не ну я не говорю что с коррелированными подзапросами или UNION ALL 3х таблиц по JOIN + PIVOT лучше, но проверить-то стоит...
Иными словами - я вам предлагаю разные варианты, но без знания того что у вас в таблицах, какие планы и зачем - советовать больше нечего.
4 апр 12, 19:16    [12366898]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
beg_inner
Guest
вчера сама запуталась,
упрощая код.
надо посчитать 3 суммы,
в которых участвует одна и та же таблица (LinkTable),
в соединении с тремя таблицами(tab1, tab2, tab3), каждая для своей суммы,
но соединение всегда по тем же условиям в LinkTable.
и эти 3 суммы надо потом собрать в запросе k MainTable по Left Join.

в чистом виде это выглядит так:
+
create table MainTable (id int not null, cod int not null);
create table LinkTable (id int not null, num int not null, cod int not null, dataoffman datetime, dataricman datetime);
create table tab1 (num int not null, val1 int null);
create table tab2 (num int not null, val2 int null);
create table tab3 (num int not null, val3 int null);

with t1 as (
select     
p.id, 
p.cod, 
sum(isnull(r.val1,0)) as val1
from         tab1 as r
             join
             LinkTable as p
             on r.num = p.num
where P.dataoffman is not null 
  and P.dataricman is not null
group by p.id, p.cod
),
----------------------------------------------------
t2 as (
select     
p.id, 
p.cod, 
sum(  isnull(val2,0) ) as val2
from         tab2 as c
             join
             LinkTable as p
             on c.num = p.num
where p.dataoffman is not null 
  and p.dataricman is not null
group by p.id, 
         p.cod
),
----------------------------------------------------
t3 as (
select     
p.id, 
p.cod,
sum(isnull(r.val3,0)) as val3
from         tab3 as r 
             join
             LinkTable as p
             on r.num = p.num
where p.dataoffman is not null
  and p.dataricman is not null
group by p.id,
         p.cod
)
----------------------------------------------------

select p.id,
       p.cod,
       a.val3,
       c.val2,
       t.val1
from MainTable p
     left join t2 c
     on c.id = p.id and
        c.cod = p.cod      
     left join t3 a
     on a.id = p.id and
        a.cod = p.cod      
     left join t1 t
     on t.id = p.id and
        t.cod = p.cod      


есть подозрение, что можно сделать проще,
не вычитывая 3 раза LinkTable.
пробовала подсчет сумм собрать в одном запросе, где присоединяю k LinkTable 3 таблицы по left join.
и это считает неправильно.
потом сделала изврат, как в первом посте.
но все равно это 3 раза вычитывание.
вопрос был, можно ли 3 раза не читать LinkTable
5 апр 12, 14:36    [12370561]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
beg_inner,
полагаю оптимизатор умней чем вы думали. хехе
5 апр 12, 14:49    [12370656]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
iljy
Member

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

а в одном запросе присоединить все таблицы к LinkTable и делать одну группировку по всему этому не?
5 апр 12, 14:49    [12370661]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
beg_inner
Guest
iljy,

так сделала в самом начале, считает неправильно, суммы вылазят больше чем надо.
что-то задваивается
5 апр 12, 14:51    [12370677]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
qwerty112
Guest
select m.id, m.cod, isnull(d.xz1,0) as xz1, isnull(d.xz2,0) as xz2, isnull(d.xz3,0) as xz3
from MainTable m

left join

	(select l.id, l.cod, sum(xz1) as xz1, sum(xz2) as xz2, sum(xz3) as xz3
	from LinkTable l
	left join	(select num, sum(val1) as xz1 from tab1 group by num) a
		on l.num=a.num
	left join	(select num, sum(val2) as xz2 from tab2 group by num) b
		on l.num=b.num
	left join	(select num, sum(val3) as xz3 from tab3 group by num) c
		on l.num=c.num
	where l.dataoffman is not null
	  and l.dataricman is not null
	group by l.id, l.cod 	
	) d

on m.id = d.id and m.cod = d.cod 
5 апр 12, 15:00    [12370733]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
qwerty112,
все хорошо, только почему то запрос автора выдает другой результат
5 апр 12, 15:24    [12370932]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
beg_inner
Guest
qwerty112,

да, так считает правильно.
у меня не хватало внутренней группировки по num.
спасибо!
наверное у меня все же суммы меньше были,
откуда им быть больше, если я внутри по num не суммировала..
5 апр 12, 15:25    [12370941]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
Мистер Хенки
qwerty112,
все хорошо, только почему то запрос автора выдает другой результат

извиняюсь, результаты идентичны, но порядок вывода разный
5 апр 12, 15:38    [12371072]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
iap
Member

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

MainTable.id, LinkTable.id, tab1.num, tab2.num, tab3.num - это уникальные ключи?
Если нет, то что является первичными ключами Ваших таблиц?
5 апр 12, 15:52    [12371217]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
beg_inner
Guest
iap
beg_inner,

MainTable.id, LinkTable.id, tab1.num, tab2.num, tab3.num - это уникальные ключи?
Если нет, то что является первичными ключами Ваших таблиц?


в MainTable: PK id, cod,
во всех остальных:
это не таблицы, а вью.
каждое вью записано как
(пример для tab1):
select * from DB.dbo.tab1 union all select * from DBARK.dbo.tab1

в каждой таблице по-отдельности (DB.dbo.tab1 и DBARK.dbo.tab1) id это ПК,
но т.к. они делают UNION ALL, то получается бардак.
мне уже попадались дубли по num, не помню в каком из вью.
исправить нет возможности т.к. на DBARK только CONNECT, SELECT,
им жаловались, ни ответа ни привета,
по идее в DBARK попадают отделенные из DB.tab1 устаревшие записи,
id не должны дублироваться , но кто-то руками что-то правил..
5 апр 12, 16:59    [12371739]     Ответить | Цитировать Сообщить модератору
 Re: посчитать 3 суммы оптимально  [new]
beg_inner
Guest
qwerty112,
а все же почему вот такой вариант дает суммы БОЛьШЕ чем надо?
вроде ж наоборот, не происходит группировка по num?

with d as
(select l.id, 
        l.cod, 
        sum(val1) as xz1, 
        sum(val2) as xz2, 
        sum(val3) as xz3
from LinkTable l
left join	tab1  a
	on l.num=a.num
left join	tab2 b
	on l.num=b.num
left join	tab3  c
	on l.num=c.num
where l.dataoffman is not null
  and l.dataricman is not null
group by l.id, l.cod 	
) 

select m.id, 
       m.cod, 
       isnull(d.xz1,0) as xz1, 
       isnull(d.xz2,0) as xz2, 
       isnull(d.xz3,0) as xz3
from MainTable m
	left join d
	on m.id = d.id and m.cod = d.cod 
5 апр 12, 18:16    [12372321]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить