Добро пожаловать в форум, Guest >> Войти | Регистрация | Поиск | Правила | | В избранное | Подписаться | ||
Все форумы / Microsoft SQL Server |
![]() ![]() |
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] Ответить | Цитировать Сообщить модератору |
Добрый Э - Эх
Guest |
0xdeface, почитай про case |
24 ноя 16, 05:49 [19928108] Ответить | Цитировать Сообщить модератору |
0xdeface Member Откуда: Сообщений: 3 |
читал, не могу понять как его применить |
24 ноя 16, 06:12 [19928110] Ответить | Цитировать Сообщить модератору |
aleks2
Guest |
Печально. 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] Ответить | Цитировать Сообщить модератору |
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] Ответить | Цитировать Сообщить модератору |
кролик-зануда
Guest |
0xdeface, у вас где именно в понимании проблема? вы не можете перевести текст на русский или его смысл после перевода остается для вас загадкой? |
24 ноя 16, 09:12 [19928311] Ответить | Цитировать Сообщить модератору |
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 | ![]() |