Задача по 1С - в базе данных есть таблица движения товара, пишем запрос для определения среднего значения остатка товара

01.03.22

Разработка - Запросы

В базе данных есть таблица движения товара, плюс означает, что товар пришел на склад, минус означает, что товар выбыл со склада: Необходимо написать запрос на 1С или SQL (по желанию), который вернет среднее значение остатка товара за январь 2021 (с 1 по 31). В результате должно получиться ProdID 1 = 1.58 ProdID 2 = 0.77

Итак, изложу свой способ решения, не претендую на идеальный, пишите, если что-то не так.

1. Нашел формулу расчета, исходя из ответа -  получаю ОстатокНаКонецДня на каждый день месяца, суммирую и делю на количество дней в месяце.

2. Кратко о запросе, получил остатки на конец дня, номера дней в месяце по дате, нарастающим итогом собрал суммы за месяц.

В параметрах таблица как на картинке и ДатаОкончания - 31.01.2022

 

Сам запрос:

ВЫБРАТЬ
	ТаблицаДвижений.ProdiD КАК ProdiD,
	ТаблицаДвижений.Количество КАК Количество,
	ТаблицаДвижений.cDate КАК cDate
ПОМЕСТИТЬ ТабДвижений
ИЗ
	&ТаблицаДвижений КАК ТаблицаДвижений
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ТабДвижений.ProdiD КАК ProdiD,
	ТабДвижений.Количество КАК Количество,
	ТабДвижений.cDate КАК cDate,
	СУММА(ТабДвижений1.Количество) КАК Количество1
ПОМЕСТИТЬ ОстатокНаКонецДня
ИЗ
	ТабДвижений КАК ТабДвижений
		ЛЕВОЕ СОЕДИНЕНИЕ ТабДвижений КАК ТабДвижений1
		ПО ТабДвижений.cDate >= ТабДвижений1.cDate
			И ТабДвижений.ProdiD = ТабДвижений1.ProdiD

СГРУППИРОВАТЬ ПО
	ТабДвижений.ProdiD,
	ТабДвижений.Количество,
	ТабДвижений.cDate
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ОстатокНаКонецДня.ProdiD КАК ProdiD,
	ОстатокНаКонецДня.cDate КАК cDate,
	ОстатокНаКонецДня.Количество1 КАК Количество1
ПОМЕСТИТЬ НомерДняВр
ИЗ
	ОстатокНаКонецДня КАК ОстатокНаКонецДня
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	НомерДняВр.ProdiD КАК ProdiD,
	&ДатаОкончания КАК ДатаОкончания
ПОМЕСТИТЬ КонецМесяца
ИЗ
	НомерДняВр КАК НомерДняВр
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	НомерДняВр.ProdiD КАК ProdiD,
	НомерДняВр.cDate КАК cDate,
	НомерДняВр.Количество1 КАК Количество
ПОМЕСТИТЬ ДвиженияПлюсКонецМесяца
ИЗ
	НомерДняВр КАК НомерДняВр

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ РАЗЛИЧНЫЕ
	КонецМесяца.ProdiD,
	КонецМесяца.ДатаОкончания,
	0
ИЗ
	КонецМесяца КАК КонецМесяца
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ДвиженияПлюсКонецМесяца.ProdiD КАК ProdiD,
	ДвиженияПлюсКонецМесяца.cDate КАК cDate,
	ДвиженияПлюсКонецМесяца.Количество КАК Количество,
	ДЕНЬ(ДвиженияПлюсКонецМесяца.cDate) КАК День
ПОМЕСТИТЬ НомерДня
ИЗ
	ДвиженияПлюсКонецМесяца КАК ДвиженияПлюсКонецМесяца
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	НомерДня.ProdiD КАК ProdiD,
	НомерДня.cDate КАК cDate,
	НомерДня.Количество КАК Количество,
	НомерДня.День КАК День,
	КОЛИЧЕСТВО(НомерДня1.cDate) КАК Номер
ПОМЕСТИТЬ НумерацияСтрок
ИЗ
	НомерДня КАК НомерДня
		ЛЕВОЕ СОЕДИНЕНИЕ НомерДня КАК НомерДня1
		ПО НомерДня.cDate >= НомерДня1.cDate
			И НомерДня.ProdiD = НомерДня1.ProdiD

СГРУППИРОВАТЬ ПО
	НомерДня.ProdiD,
	НомерДня.cDate,
	НомерДня.Количество,
	НомерДня.День
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	НумерацияСтрок.ProdiD КАК ProdiD,
	НумерацияСтрок.cDate КАК cDate,
	НумерацияСтрок.Количество КАК Количество,
	НумерацияСтрок.День КАК День,
	НумерацияСтрок.Номер КАК Номер,
	НумерацияСтрок1.День КАК День1,
	ВЫБОР
		КОГДА НЕ НумерацияСтрок1.День ЕСТЬ NULL
			ТОГДА ВЫБОР
					КОГДА НумерацияСтрок1.День = ДЕНЬ(&ДатаОкончания)
						ТОГДА НумерацияСтрок1.День - НумерацияСтрок.День + 1
					ИНАЧЕ НумерацияСтрок1.День - НумерацияСтрок.День
				КОНЕЦ
		ИНАЧЕ 0
	КОНЕЦ КАК КолДнейПериодОстатка
ПОМЕСТИТЬ ВрТч
ИЗ
	НумерацияСтрок КАК НумерацияСтрок
		ЛЕВОЕ СОЕДИНЕНИЕ НумерацияСтрок КАК НумерацияСтрок1
		ПО (НумерацияСтрок.Номер = НумерацияСтрок1.Номер - 1)
			И НумерацияСтрок.ProdiD = НумерацияСтрок1.ProdiD

СГРУППИРОВАТЬ ПО
	НумерацияСтрок.ProdiD,
	НумерацияСтрок.cDate,
	НумерацияСтрок.Количество,
	НумерацияСтрок.День,
	НумерацияСтрок.Номер,
	НумерацияСтрок1.День
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ВрТч.ProdiD КАК ProdiD,
	ВрТч.cDate КАК cDate,
	ВрТч.Количество КАК Количество,
	ВрТч.День КАК День,
	ВрТч.Номер КАК Номер,
	ВрТч.День1 КАК День1,
	ВрТч.КолДнейПериодОстатка КАК КолДнейПериодОстатка,
	ВЫБОР
		КОГДА ВрТч.КолДнейПериодОстатка > 0
				И ВрТч.Количество > 0
			ТОГДА ВрТч.КолДнейПериодОстатка * ВрТч.Количество
		ИНАЧЕ 0
	КОНЕЦ КАК СуммаОстаткаПоПериоду
ПОМЕСТИТЬ ИтоговыеДанные
ИЗ
	ВрТч КАК ВрТч
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ИтоговыеДанные.ProdiD КАК ProdiD,
	СУММА(ИтоговыеДанные.СуммаОстаткаПоПериоду) КАК СуммаОстаткаПоПериоду
ПОМЕСТИТЬ СуммировалОстатки
ИЗ
	ИтоговыеДанные КАК ИтоговыеДанные

СГРУППИРОВАТЬ ПО
	ИтоговыеДанные.ProdiD
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	СуммировалОстатки.ProdiD КАК ProdiD,
	СуммировалОстатки.СуммаОстаткаПоПериоду КАК СуммаОстаткаПоПериоду,
	ВЫРАЗИТЬ(СуммировалОстатки.СуммаОстаткаПоПериоду / ДЕНЬ(&ДатаОкончания) КАК ЧИСЛО(15, 2)) КАК aCount
ИЗ
	СуммировалОстатки КАК СуммировалОстатки

 

Вступайте в нашу телеграмм-группу Инфостарт

в базе данных есть таблица движения товара плюс означает что товар пришел на склад минус выбыл со склада

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

16500 руб.

02.09.2020    259249    1430    421    

1165

WEB-интеграция Запросы Программист 1С 8.3 Абонемент ($m)

Post1C - это внешняя обработка, которая превращает 1С в полноценный инструмент для тестирования REST API. Всё управление сосредоточено в одном окне: настройка запроса, выполнение, просмотр ответа и генерация кода - без переключения между формами. Аналог Postman, но работающий в привычной среде 1С.

1 стартмани

02.04.2026    2252    68    priem_nv    23    

65

Инструментарий разработчика Запросы Программист 1С 8.3 1С:Библиотека стандартных подсистем Абонемент ($m)

Представляю новую версию подсистемы работы со схемой запроса, которая завершает её эволюцию от библиотеки по работе со схемой запроса до объектной реализации модели запроса 2. Теперь есть выбор между классическим и текучим стилем написанию кода - оба варианта взаимозаменяемы. Ключевое улучшение - использование объектов в качестве источников данных, значений полей и параметров в условиях виртуальных таблиц, а также новые операторы позиционирования в схеме

1 стартмани

29.03.2026    1804    kalyaka    16    

24

Инструментарий разработчика Запросы Программист 1С:Предприятие 8 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

QueryConsole1C — расширение, включающее консоль запросов с поддержкой исполняемых представлений — аналогов виртуальных таблиц, основанных на методах программного интерфейса ЗУП. Оно позволяет выполнять запросы с учётом встроенной бизнес-логики, отлаживать алгоритмы получения данных и автоматически генерировать код на встроенном языке 1С.

1 стартмани

16.05.2025    11269    148    zup_dev    30    

83

Инструментарий разработчика Запросы Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)

В данной публикации рассказывается о решении, которое позволяет находить сразу все ошибки в тексте запроса за раз, а не только самую первую.

2 стартмани

05.03.2025    6539    21    XilDen    12    

29

Обновление 1С Запросы Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)

Данный инструмент помогает анализировать доработанную конфигурацию после обновления на новый релиз и находить «битые» тексты запросов, в которых участвуют несуществующие в новом релизе метаданные.

3 стартмани

06.02.2025    5807    36    XilDen    26    

42

Запросы Программист 1С:Предприятие 8 1C:Бухгалтерия Бесплатно (free)

В статье приведена удобная возможность отладки исполняемого запроса динамического списка.

03.12.2024    13049    artemusII    11    

27
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. user1559647 23.08.22 23:56 Сейчас в теме
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	ТабДвижений.ProdId КАК ProdiD,
	ТабДвижений.Count КАК Count,
	ТабДвижений.cDate КАК cDate,
	СУММА(ТабДвижений1.Count) КАК Count1
ПОМЕСТИТЬ ОстаткиНаКонецДня
ИЗ
	РегистрСведений.ТаблицаДвижений КАК ТабДвижений
			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ТаблицаДвижений КАК ТабДвижений1
			ПО ТабДвижений.cDate >= ТабДвижений1.cDate
				И ТабДвижений.ProdId = ТабДвижений1.ProdId
		
СГРУППИРОВАТЬ ПО
	ТабДвижений.ProdId,
	ТабДвижений.Count,
	ТабДвижений.cDate
	;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ОстаткиНаКонецДня.ProdiD КАК ProdiD,
	Сумма(Выразить(ОстаткиНаКонецДня.Count1 * РазностьДат(ОстаткиНаКонецДня.cDate, ЕстьNull(ОстаткиНаКонецДня1.cDate, ДобавитьКДате(&ДатаКон, ДЕНЬ, 1)), ДЕНЬ)/День(&ДатаКон) КАК Число(10, 3))) КАК aCount	
ИЗ
	ОстаткиНаКонецДня КАК ОстаткиНаКонецДня
        Левое Соединение ОстаткиНаКонецДня КАК ОстаткиНаКонецДня1
        ПО ОстаткиНаКонецДня.ProdiD = ОстаткиНаКонецДня1.ProdiD
        И ОстаткиНаКонецДня.cDate < ОстаткиНаКонецДня1.cDate 
Сгруппировать По
 ОстаткиНаКонецДня.ProdID 
        
;
Показать



Создал непереодический регистр сведений ТаблицаДвижений с измерениями cDate и ProdId и ресурсом Count и занес туда условие задачи
user622095_admin; +1 Ответить
2. Greamdevil 6 24.08.22 04:59 Сейчас в теме
дак само собой на регистрах все просто, суть в том что регистрами нельзя пользоваться :)
3. user1559647 24.08.22 23:05 Сейчас в теме
(2) а что я использовал из возможностей регистров? никаких срезов, только основная таблица, даже регистр непериодический
4. pvlunegov 160 09.03.23 10:24 Сейчас в теме
Зачем такие сложные запросы?
Вполне достаточно очень простого запроса:
ВЫБРАТЬ
	ДвиженияТовара.cDate,
	ДвиженияТовара.ProdID,
	ДвиженияТовара.Count
ПОМЕСТИТЬ ТаблицаДвиженийТоваров
ИЗ
	&ДвиженияТовара КАК ДвиженияТовара
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КОНЕЦПЕРИОДА(ТаблицаДвиженийТоваров.cDate, МЕСЯЦ) КАК КонецМесяца,
	ТаблицаДвиженийТоваров.ProdID КАК ID_Товара,
	СУММА(ТаблицаДвиженийТоваров.Count) КАК Количество
ИЗ
	ТаблицаДвиженийТоваров КАК ТаблицаДвиженийТоваров

СГРУППИРОВАТЬ ПО
	ТаблицаДвиженийТоваров.ProdID,
	КОНЕЦПЕРИОДА(ТаблицаДвиженийТоваров.cDate, МЕСЯЦ)
Показать


группировка дат из первой таблицы помесячно, по ID товара. суммируем все записи таблицы по группировкам (конец месяца, ID товара). Получим суммы движений товаров (остаток) на конец каждого месяца.
В последней таблице дополнительно наложил условие на то, что месяц = январь (номер месяца = 1)
5. user1647484 9 17.03.23 10:45 Сейчас в теме
как не старался посчитать, но получаю результаты ProdID1 = 1 ProdID2 = 0.5
6. mrGREYka 6 20.02.24 12:56 Сейчас в теме
DECLARE @startDate DATE	= '2021-01-01';
DECLARE @endDate DATE	= '2021-01-31';

IF EXISTS( Sel ect ID fr om tempdb..sysobjects  where id = OBJECT_ID( 'tempdb..' + LTRIM( RTRIM( '#all_day_of_month' ) ) ) )
	BEGIN
		DR OP   TABLE #all_day_of_month;
	END


SEL ECT [Date] = DATEADD(Day,Number,@startDate) 
INTO
	#all_day_of_month
FROM  master..spt_values 
WH ERE Type='P'
AND DATEADD(day,Number,@startDate) <= @endDate;

DECLARE @count_day_of_month INT = ( SELECT COUNT(*) FR OM #all_day_of_month );

SELECT 
	remains.[ProdID] AS ProdID
	,CONVERT( numeric(10,2),( SUM( remains.[Count] ) / @count_day_of_month ) ) AS aCount
FR OM 
	#all_day_of_month AS all_day_of_month
JOIN
	[dbo].[remains] AS remains
		ON remains.cDate <= all_day_of_month.[Date]
GROUP BY
	remains.[ProdID];
Показать
Прикрепленные файлы:
7. aleks xantaev 8 09.07.24 12:31 Сейчас в теме

ВЫБРАТЬ
	Таб.cDate,
	Таб.ProdID,
	Таб.Count
ПОМЕСТИТЬ ВТ
ИЗ
	&Таб КАК Таб
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ.cDate,
	ВТ.ProdID
ПОМЕСТИТЬ ВТПериоды
ИЗ
	ВТ КАК ВТ

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	МАКСИМУМ(НАЧАЛОПЕРИОДА(ВТ.cDate, МЕСЯЦ)),
	ВТ.ProdID
ИЗ
	ВТ КАК ВТ

СГРУППИРОВАТЬ ПО
	ВТ.ProdID

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	МАКСИМУМ(КОНЕЦПЕРИОДА(ВТ.cDate, МЕСЯЦ)),
	ВТ.ProdID
ИЗ
	ВТ КАК ВТ

СГРУППИРОВАТЬ ПО
	ВТ.ProdID
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТПериоды.ProdID КАК ProdID,
	ВТПериоды.cDate КАК НачалоПериода,
	МИНИМУМ(ВЫБОР
			КОГДА ВТПериоды1.cDate = КОНЕЦПЕРИОДА(ВТПериоды1.cDate, МЕСЯЦ)
				ТОГДА КОНЕЦПЕРИОДА(ВТПериоды1.cDate, МЕСЯЦ)
			ИНАЧЕ ДОБАВИТЬКДАТЕ(ВТПериоды1.cDate, ДЕНЬ, -1)
		КОНЕЦ) КАК ОкончаниеПериода
ПОМЕСТИТЬ ВТИнтервалы
ИЗ
	ВТПериоды КАК ВТПериоды
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТПериоды КАК ВТПериоды1
		ПО ВТПериоды.cDate < ВТПериоды1.cDate
			И ВТПериоды.ProdID = ВТПериоды1.ProdID

СГРУППИРОВАТЬ ПО
	ВТПериоды.cDate,
	ВТПериоды.ProdID
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТИнтервалы.ProdID,
	ВТИнтервалы.НачалоПериода,
	ВТИнтервалы.ОкончаниеПериода,
	ВТПериоды.cDate
ПОМЕСТИТЬ ВТ3
ИЗ
	ВТИнтервалы КАК ВТИнтервалы
		ЛЕВОЕ СОЕДИНЕНИЕ ВТПериоды КАК ВТПериоды
		ПО ВТИнтервалы.ProdID = ВТПериоды.ProdID
			И ВТИнтервалы.НачалоПериода = ВТПериоды.cDate
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТ3.ProdID,
	ВТ3.НачалоПериода,
	ВТ3.ОкончаниеПериода,
	СУММА(ВТ.Count) КАК Count
ПОМЕСТИТЬ ВТИтог
ИЗ
	ВТ КАК ВТ
		ЛЕВОЕ СОЕДИНЕНИЕ ВТ3 КАК ВТ3
		ПО ВТ.cDate <= ВТ3.cDate
			И ВТ.ProdID = ВТ3.ProdID
СГРУППИРОВАТЬ ПО
	ВТ3.НачалоПериода,
	ВТ3.ОкончаниеПериода,
	ВТ3.ProdID
;
////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	ВТИтог.ProdID,
	ВЫРАЗИТЬ(СУММА((РАЗНОСТЬДАТ(ВТИтог.НачалоПериода, ВТИтог.ОкончаниеПериода, ДЕНЬ) + 1) * ВТИтог.Count) / 31 КАК ЧИСЛО(10, 2)) КАК aCount
ИЗ
	ВТИтог КАК ВТИтог

СГРУППИРОВАТЬ ПО
	ВТИтог.ProdID


Показать
8. khakasia 150 16.12.24 19:21 Сейчас в теме
Для отправки сообщения требуется регистрация/авторизация