Задача по 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
ИЗ
	СуммировалОстатки КАК СуммировалОстатки

 

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

См. также

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

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

15500 руб.

02.09.2020    178192    988    403    

946

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

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

2 стартмани

06.02.2025    1813    14    XilDen    26    

35

Запросы Программист Бесплатно (free)

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    12453    sergey279    18    

65

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

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    7485    XilDen    36    

90

Запросы Программист Запросы Бесплатно (free)

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

16.08.2024    10118    user1840182    5    

29

Математика и алгоритмы Запросы Программист Платформа 1С v8.3 Запросы Бесплатно (free)

Рассмотрим быстрый алгоритм поиска дублей с использованием hash функции по набору полей шапки и табличных частей.

08.07.2024    3019    ivanov660    9    

22

Запросы СКД Программист Стажер Система компоновки данных Россия Бесплатно (free)

Часто при разработке отчетов в СКД возникает ситуация, когда не совсем понятно, почему отчет выводит не те данные, которые нужны, либо не выводит вовсе. Возникает потребность увидеть конечный запрос, который формирует СКД. Как это сделать, рассмотрим в этой статье.

15.05.2024    12047    implecs    6    

49
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
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 144 16.12.24 19:21 Сейчас в теме
Оставьте свое сообщение