|
v7: В результате выполнения запроса "нехватка оперативной памяти" | ☑ | ||
---|---|---|---|---|
0
zenon46
28.12.19
✎
13:09
|
Доброго дня! Есть запрос для получения остатков оборотов и поступлений (с отбором по виду документа), в разрезе каждого дня из интервала, но в результате по большому периоду и большому списку номенклатуры, имеем падение предприятия с ошибкой в нехватке оперативной памяти. Как можно оптимизировать / переделать запрос, что бы мы имели по товару "свернутые" цифры по интервалу, начальный остаток посчитаем отдельно.
Вот собственно запрос : МетаДата = СоздатьОбъект("MetaDataWork"); ТекстЗапроса = " |SET NOCOUNT ON |; |IF EXISTS(SELECT * FROM tempdb..sysobjects WHERE id = object_id('tempdb..#Период')) | DROP TABLE #Период |; |CREATE TABLE #Период (val char(9) PRIMARY KEY) |; |DECLARE @НачДата as DATETIME |SET @НачДата = '"+МетаДата.ПолучитьСтрИзДаты(НачДатаПрод)+"' |DECLARE @КонДата as DATETIME |SET @КонДата = '"+МетаДата.ПолучитьСтрИзДаты(КонДатаПрод)+"' |WHILE @НачДата <= @КонДата |BEGIN |INSERT INTO #Период VALUES (CONVERT(char(8), @НачДата, 112)) |SET @НачДата = dateadd(DAY, 1, @НачДата) |END |; |IF EXISTS(SELECT * FROM tempdb..sysobjects WHERE id = object_id('tempdb..#Итоги')) | DROP TABLE #Итоги |; |CREATE TABLE #Итоги (Дата char(8), Товар char(9), Остаток float, Оборот float, Поступление float) |; |CREATE INDEX DateItem ON #Итоги (Товар,Дата) |; |INSERT INTO #Итоги (Дата,Товар,Остаток,Оборот,Поступление) |SELECT | ДатыТовары.Дата as [Дата $Дата], | ДатыТовары.Товар as [Товар $Справочник.Номенклатура], | SUM(ДатыТовары.Остаток) as [Остаток $Число], | SUM(ДатыТовары.Оборот) as [Оборот $Число], | SUM(ДатыТовары.Поступление) as [Поступление $Число] |FROM | (SELECT | #Период.val as [Дата], | #TempTable.val as [Товар], | 0 as [Остаток], | 0 as [Оборот], | 0 as [Поступление] | FROM | #Период CROSS JOIN #TempTable |UNION ALL | SELECT | :НачДата, | Остатки.Номенклатура, | Остатки.КоличествоОстаток, | 0, | 0 |FROM | $РегистрОстатки.ОстаткиТМЦ(:НачДата,,Фирма = :ВыбФирма AND Номенклатура IN (SELECT val FROM #TempTable),(Номенклатура),(Количество)) as Остатки |UNION ALL | SELECT | SUBSTRING(Обороты.Date_Time_Iddoc,1,8) AS [Дата], | $Обороты.Номенклатура AS [Товар], | 0 AS [Остаток], | SUM(CASE WHEN Обороты.DEBKRED = 0 THEN $Обороты.Количество ELSE $Обороты.Количество * (-1) END) AS [Оборот], | SUM(CASE WHEN Обороты.IDDOCDEF = $ВидДокумента.ПоступлениеТМЦ_Склад THEN $Обороты.Количество ELSE 0 END) AS [Поступление] | FROM | $Регистр.ОстаткиТМЦ as Обороты | WHERE | Обороты.Date_Time_Iddoc between :НачДата AND :КонДата~ AND | $Обороты.Номенклатура IN (SELECT val FROM #TempTable) AND | $Обороты.Фирма = :ВыбФирма | GROUP BY | SUBSTRING(Обороты.Date_Time_Iddoc, 1, 8), $Обороты.Номенклатура, Обороты.IDDoc | ) as ДатыТовары |GROUP BY | ДатыТовары.Дата, ДатыТовары.Товар |; |DROP TABLE #Период |; |DECLARE @CurrentMove as float |DECLARE @CurrentQty as float |DECLARE @NextQty as float |DECLARE @CurrentItem as char(9) |DECLARE @LastItem as char(9) |SET @LastItem = '' | |DECLARE cur CURSOR LOCAL FORWARD_ONLY FOR |SELECT Оборот,Товар,Остаток |FROM #Итоги |ORDER BY Товар,Дата |FOR UPDATE | |OPEN cur |FETCH NEXT FROM cur INTO @CurrentMove, @CurrentItem, @CurrentQty |WHILE @@FETCH_STATUS = 0 |BEGIN | IF NOT @LastItem = @CurrentItem | BEGIN | SET @NextQty = @CurrentQty + @CurrentMove | SET @LastItem = @CurrentItem | END | ELSE | BEGIN | UPDATE #Итоги | SET Остаток = @NextQty | WHERE CURRENT OF cur | SET @NextQty = @NextQty + @CurrentMove | END |FETCH NEXT FROM cur INTO @CurrentMove, @CurrentItem, @CurrentQty |END |; |CLOSE cur |; |deallocate cur |; |SELECT | Товары.CODE as [Код $Строка], | Итоги.Товар as [Номенклатура $Справочник.Номенклатура], | Итоги.Остаток as [Остаток $Число], | Итоги.Поступление as [Поступление $Число], | Итоги.Дата as [Дата $Дата], | Итоги.Остаток + Итоги.Оборот as [ОстатокКонДень $Число], | (Итоги.Остаток + (Итоги.Остаток + Итоги.Оборот))/2 as [СредДневОстаток $Число] |FROM | #Итоги as Итоги | JOIN $Справочник.Номенклатура as Товары ON Итоги.Товар = Товары.ID |ORDER BY | Итоги.Дата, Товары.DESCR, Товары.ID |; |DROP TABLE #Итоги |; |SET NOCOUNT OFF |"; |
|||
1
zenon46
28.12.19
✎
14:52
|
Вроде как обошлось просто через SUM сделать, проверяю.
|
|||
2
zenon46
28.12.19
✎
14:55
|
Хотя это не правильно(
|
|||
3
Злопчинский
28.12.19
✎
15:10
|
(0) "остатков оборотов и поступлений"
меня напрягает эта фраза.. какие остатки ОБОРОТОВ? оборот - он и есть оборот. за период. какой у него остаток? |
|||
4
zenon46
28.12.19
✎
15:12
|
там запятой не хватает)
"остатков, оборотов, поступлений" |
|||
5
zenon46
28.12.19
✎
15:13
|
получается из всего запроса, сумму можно дернуть только по Итоги.Поступление as [Поступление $Число], и (Итоги.Остаток + (Итоги.Остаток + Итоги.Оборот))/2 as [СредДневОстаток $Число], а дальше нужен остаток на начало периода и остаток на конец периода.
|
|||
6
Злопчинский
28.12.19
✎
15:13
|
поступлений - считаешь оборот поступлений?
|
|||
7
zenon46
28.12.19
✎
15:16
|
(6) $ВидДокумента.ПоступлениеТМЦ_Склад THEN $Обороты.Количество ELSE 0 END) AS [Поступление] только то что пришло по этому виду документов
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |