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

Откуда:
Сообщений: 3
Здравствуйте, бьюсь с запросом уже очень долгое время, попутно читая книжку по sql.
Вообщем я составил запрос но он очень долго работает, есть мысли как его можно упростить но уперся в трудность - незнаю как сумировать строки по условию без выполнения join
Вот мои исходный запрос, он работает но очень долго:
  select sklad.code, nom.code, (sp411 - isnull(rashod.k,0) + isnull(prihod.k,0)) as cnt from rg405 as rg WITH(NOLOCK)
        left join(
	      select debkred, sp408, sp418, sum(sp411) as k
	      from ra405 as r WITH(NOLOCK)
	      left join _1SJOURN as j WITH(NOLOCK)
	      on j.iddoc = r.iddoc
	      where (cast(substring(date_time_iddoc,1,8)as date)) > '2016-11-01' and debkred=1
	      GROUP BY sp408, sp418, debkred
	      ) as rashod
          on rashod.sp408 = rg.sp408 and rashod.sp418 = rg.sp418
        left join(
	      select debkred, sp408, sp418, sum(sp411) as k
	      from ra405 as r WITH(NOLOCK)
	      left join _1SJOURN as j WITH(NOLOCK)
	      on j.iddoc = r.iddoc
	      where (cast(substring(date_time_iddoc,1,8)as date)) > '2016-11-01' and debkred=0
	      GROUP BY sp408, sp418, debkred
	      ) as prihod
        on prihod.sp408 = rg.sp408 and prihod.sp418 = rg.sp418
        join sc84 as nom WITH(NOLOCK)
        on rg.sp408 = nom.id
        join SC55 as sklad WITH(NOLOCK)
        on rg.sp418 = sklad.id
        where period = '2016-11-01' order by nom.descr;
 

Начал переделывать вот первый кусок
select debkred, sp408, sp418, sum(sp411) as k
 from ra405 as r WITH(NOLOCK)
 inner join _1SJOURN as j WITH(NOLOCK)
-- перенес условие в join и сделал его inner стало быстрее в 2 раза
 on j.iddoc = r.iddoc and cast(substring(j.date_time_iddoc,1,8)as date) > '2016-11-01'
 GROUP BY sp408, sp418, debkred 
-- убрал выборку по debkred

в результате у меня есть данные в которы необходимо вычислить последнюю колонку, отняв дебет от кредита, для тех строк у которых соответствуют 2 и 3 колонка как ниже
1 / A / B/ 4
0 / A/ B / 3
24 ноя 16, 05:37    [19928106]     Ответить | Цитировать Сообщить модератору
 Re: Суммировать строки результата по условию  [new]
Добрый Э - Эх
Guest
0xdeface,

почитай про case
24 ноя 16, 05:49    [19928108]     Ответить | Цитировать Сообщить модератору
 Re: Суммировать строки результата по условию  [new]
0xdeface
Member

Откуда:
Сообщений: 3
читал, не могу понять как его применить
24 ноя 16, 06:12    [19928110]     Ответить | Цитировать Сообщить модератору
 Re: Суммировать строки результата по условию  [new]
aleks2
Guest
0xdeface
[/src]
Начал переделывать вот первый кусок
select debkred, sp408, sp418, sum(sp411) as k
 from ra405 as r WITH(NOLOCK)
 inner join _1SJOURN as j WITH(NOLOCK)
-- перенес условие в join и сделал его inner стало быстрее в 2 раза
 on j.iddoc = r.iddoc and cast(substring(j.date_time_iddoc,1,8)as date) > '2016-11-01'
 GROUP BY sp408, sp418, debkred 
-- убрал выборку по debkred


Печально.

1. Перестаньте писать фигню
cast(substring(j.date_time_iddoc,1,8)as date) > '2016-11-01'
это пишется так
j.date_time_iddoc > '20161101' -- надеюсь 11 - это месяц

Иначе сервер будет тупо читать ВСЮ _1SJOURN - у него других вариантов нема.

2. Ваша группировка обрабатывает соединение двух гигантских таблиц. Да ишо и ДВА раза.
2.1. Рассмотрите возможности пронести ограничения на выборку ПОД группировку или, на худой конец, группируйте один раз во временную таблицу.
2.2. По уму, надо сначала выбрать во времянку все нужные iddoc.
24 ноя 16, 06:58    [19928129]     Ответить | Цитировать Сообщить модератору
 Re: Суммировать строки результата по условию  [new]
0xdeface
Member

Откуда:
Сообщений: 3
Да, это месяц.
Вот я пытаюсь без джоинов используя case переписать
;with cte as (
  select sp408, sp418,  k = case 
  when debkred=1  then sp411
  when debkred=0 then sp411*-1
  end
  from ra405 as r WITH(NOLOCK)
  inner join _1SJOURN as j WITH(NOLOCK)
  on j.iddoc = r.iddoc and cast(substring(j.date_time_iddoc,1,8)as date) > '2016-11-01'
  ) 
 SELECT * from cte GROUP BY sp408, sp418, sum(k);

но получаю ошибку, понимаю что она значит но как сделать не знаю.
Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY claus
24 ноя 16, 07:09    [19928136]     Ответить | Цитировать Сообщить модератору
 Re: Суммировать строки результата по условию  [new]
кролик-зануда
Guest
0xdeface,

у вас где именно в понимании проблема?
вы не можете перевести текст на русский или его смысл после перевода остается для вас загадкой?
24 ноя 16, 09:12    [19928311]     Ответить | Цитировать Сообщить модератору
 Re: Суммировать строки результата по условию  [new]
aleks2
Guest
select sp408, sp418
      , rashod = sum(case  when debkred=1 then sp411 else 0 end )
      , prihod = sum(case  when debkred=0 then sp411 else 0 end )
  from ra405 as r WITH(NOLOCK)
  inner join _1SJOURN as j WITH(NOLOCK)
  on j.iddoc = r.iddoc and cast(substring(j.date_time_iddoc,1,8)as date) > '2016-11-01'
  GROUP BY sp408, sp418


ЗЫ. Ну уберите, наконец, это фуфло cast(substring(j.date_time_iddoc,1,8)as date).
24 ноя 16, 09:26    [19928377]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить