powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / [игнор отключен] [закрыт для гостей] / SQL-щики нид хелп по вопросу количества дней в остатках
13 сообщений из 13, страница 1 из 1
SQL-щики нид хелп по вопросу количества дней в остатках
    #36606947
Last1Cmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Задача тривиальна

Нахождение количества дней в периоде когда товар присутствовал в остатках (т.е. считаем дни когда остаток товара был больше "0")

Путь "в лоб" гласит о том что делаем запрос с группировкой по дням и получим там количество записей соответсвующих искомому значению

Однако это очень небыстро т.к. периоды в несколько лет и товаров (комбинаций искомых) под мульён т.е. само собой напрашивается решение с использованием прямых запросов.

Было бы например кво дней в продажах было бы просто т.к. даты можно выкусить из движений и сгруппировать по выкушенному а как с остатками быть ?

у кого какие мысли ?
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36606973
Last1Cmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да... уточнение - с 7.7 воюем но в данному случае разницы нет
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36606989
leaf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
все движения в регистре делают регистраторы , как правило
поэтому максимум что можно пытаться сделать
это детализация до регистратора , хотя могут быть случаи когда и это хуже
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36607048
Last1Cmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
в том то и дело что не движения нужны

эмпирически можно как-то накопительными итогами вычислить остатки из движений если брать весь период существования но ВЕСЬ период нужен только один раз - а остальное - мелкие периоды сезонности где нужно иметь остаток именно на день внутри общего периода жизни товара

пс... задачка - подготовка данных для прогноза продаж и собсно обеспечения товарным запасом точек для чего необходимо знать скорость этих продаж (к-во продаж делённое на к-во дней в остатках)
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36607052
Alex.Ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имхо прямой запрос не намного ускорит дело. Все равно он должен будет для каждого товара брать остаток на начало месяца и считать по приходам/расходам для каждого дня наличие товара. Если ускорять радикально, то надо делать новую SQL таблицу или регистр какой-то, где эти данные будут храниться в явном виде. Обновляться при каждом приходе расходе. Тогда каждое проведение документа немного замедлится.
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36607061
Last1Cmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex.RuИмхо прямой запрос не намного ускорит дело. Все равно он должен будет для каждого товара брать остаток на начало месяца и считать по приходам/расходам для каждого дня наличие товара. Если ускорять радикально, то надо делать новую SQL таблицу или регистр какой-то, где эти данные будут храниться в явном виде. Обновляться при каждом приходе расходе . Тогда каждое проведение документа немного замедлится.

это тригерааа мать их и объём работ по отслеживанию каждого из регистраторов могу себе представить... за неделю я не потяну такое
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36607097
Alex.Ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какие еще тригера ? В каждом документе есть ОбработкаПроведения() , ОбработкаУдаленияПроведения(), в них и обрабатываешь. Точнее в них вставляешь глЗаполнениеЧудоТаблицы(х1,х2...) из главного модуля. Кстати в расходных накладных как правило все равно вычисляются остатки. Да и в приходных тоже. Так что объем дополнительных вычислений не большой. Преимущества SQL таблицы в том что ее можно заполнить свободно за предыдущие 100 лет. А регистр только перепроведением всех документов.
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36607491
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тестовая таблица
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
CREATE TABLE #Actions(
	Period datetime NOT NULL
	,Product nvarchar( 50 ) NOT NULL
	,ActionSum numeric( 19 ,  2 ) NOT NULL
	
	CONSTRAINT PK_Actions PRIMARY KEY (Period, Product)
)

SET NOCOUNT ON
INSERT #Actions VALUES('20100102', 'Монитор',  10 )
INSERT #Actions VALUES('20100104', 'Монитор', - 3 )
INSERT #Actions VALUES('20100110', 'Монитор',  2 )
INSERT #Actions VALUES('20100112', 'Монитор', - 5 )
INSERT #Actions VALUES('20100113', 'Монитор', - 4 )
INSERT #Actions VALUES('20100115', 'Монитор',  11 )
Запрос остатков на каждый день, выглядит страшно, но работает быстро.
Когда разберетесь, как работает, станете гуру в получении остатков :-)))
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
SELECT
	AllDates.Date
	,Actions.Product
	,SUM(Actions.ActionSum) AS ResidueSum
FROM
	(SELECT
		CASE
			WHEN
				ISDATE(CONVERT(nvarchar( 4 ),  2010  + Years.YearNumber)
					+ '-' + CONVERT(nvarchar( 2 ), Months.MonthNumber)
					+ '-' + CONVERT(nvarchar( 2 ), DayNumbers.DayNumber)
				) =  1 
			THEN CONVERT(datetime
					,CONVERT(nvarchar( 4 ),  2010  + Years.YearNumber)
					+ '-' + CONVERT(nvarchar( 2 ), Months.MonthNumber)
					+ '-' + CONVERT(nvarchar( 2 ), DayNumbers.DayNumber)
					, 120 
				)
			ELSE '17530101'
		END AS Date
	FROM
		(SELECT  1  AS DayNumber
		UNION ALL SELECT  2  UNION ALL SELECT  3  UNION ALL
		SELECT  4  UNION ALL SELECT  5  UNION ALL SELECT  6 
		UNION ALL SELECT  7  UNION ALL SELECT  8  UNION ALL
		SELECT  9  UNION ALL SELECT  10  UNION ALL SELECT  11 
		UNION ALL SELECT  12  UNION ALL SELECT  13  UNION ALL
		SELECT  14  UNION ALL SELECT  15  UNION ALL SELECT  16 
		UNION ALL SELECT  17  UNION ALL SELECT  18  UNION ALL
		SELECT  19  UNION ALL SELECT  20  UNION ALL SELECT  21 
		UNION ALL SELECT  22  UNION ALL SELECT  23  UNION ALL
		SELECT  24  UNION ALL SELECT  25  UNION ALL SELECT  26 
		UNION ALL SELECT  27  UNION ALL SELECT  28  UNION ALL
		SELECT  29  UNION ALL SELECT  30  UNION ALL SELECT  31 
		) AS DayNumbers
		
	CROSS JOIN
		(SELECT  1  AS MonthNumber
		UNION ALL SELECT  2  UNION ALL SELECT  3  UNION ALL
		SELECT  4  UNION ALL SELECT  5  UNION ALL SELECT  6 
		UNION ALL SELECT  7  UNION ALL SELECT  8  UNION ALL
		SELECT  9  UNION ALL SELECT  10  UNION ALL SELECT  11 
		UNION ALL SELECT  12 
		) AS Months

	CROSS JOIN
		(SELECT  0  AS YearNumber
		UNION ALL SELECT  1  UNION ALL SELECT  2  UNION ALL
		SELECT  3  UNION ALL SELECT  4  UNION ALL SELECT  5 
		UNION ALL SELECT  6  UNION ALL SELECT  7  UNION ALL
		SELECT  8  UNION ALL SELECT  9  UNION ALL SELECT  10 
		) AS Years
	WHERE
		ISDATE(CONVERT(nvarchar( 4 ),  2010  + Years.YearNumber)
			+ '-' + CONVERT(nvarchar( 2 ), Months.MonthNumber)
			+ '-' + CONVERT(nvarchar( 2 ), DayNumbers.DayNumber)
		) =  1 
	) AS AllDates

INNER JOIN #Actions AS Actions
ON Actions.Period <= AllDates.Date

WHERE AllDates.Date BETWEEN '20100101' AND '20100316'

GROUP BY
	AllDates.Date
	,Actions.Product

ORDER BY
	AllDates.Date
	,Actions.Product
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36608040
Last1Cmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
огромное спасибо я никак не мог понять как мне скрестить таблицу дней с движениями

теперь другой вопрос

Код: plaintext
1.
INNER JOIN #Actions AS Actions
ON Actions.Period <= AllDates.Date

не попадают записи которые есть в таблице дат до первого движения в периоде

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

почем левое соединение не работает ?!!
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36608054
Last1Cmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
работает левое внешнее х/з чего было

огромедное спасибо тварщи !!!!!
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36609667
Last1Cmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
итоговый пакет такой

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
IF OBJECT_ID ('TB','V') is not NULL
DROP VIEW TB
GO
create view TB as
select TB_DV.Skl, TB_DV.Nom, TB_DV.Razm, TB_DV.Date,  
TB_DV.Prih - TB_DV.Rash as SumK  from
	(select SP565 as Nom, SP566 as Razm, Left(DATE_TIME_IDDOC, 8 ) as Date, SP564 as Skl, 
		SUM(CASE WHEN DEBKRED =  0  THEN SP71 ELSE  0  END) as Prih, 
		SUM(CASE WHEN DEBKRED =  1  THEN SP71 ELSE  0  END) as Rash 
			from RA67
	 GROUP BY SP564,SP565,SP566, Left(DATE_TIME_IDDOC, 8 )
	) as TB_DV
GO

DECLARE @D_N char( 8 ),@D_NP char( 8 ),@D_KP char( 8 ), @Skl char( 9 )
SET @Skl = '    1MЦБ '
SET @D_NP = '20080101' -- data nach
SET @D_KP = '20100331' -- data kon
SET @D_N = '20080101' -- data nach


select All_T.Nom, All_T.Razm, COUNT(All_T.Date) as Дней from
(
SELECT
	DV.Nom,
	DV.Razm,
	AllDates.Date,
	SUM(DV.S) AS ResidueSum
FROM
(SELECT
		CASE
			WHEN
				ISDATE(CONVERT(nvarchar( 4 ),  2008  + Years.YearNumber)
					+ '-' + CONVERT(nvarchar( 2 ), Months.MonthNumber)
					+ '-' + CONVERT(nvarchar( 2 ), DayNumbers.DayNumber)
				) =  1 
			THEN CONVERT(datetime
					,CONVERT(nvarchar( 4 ),  2008  + Years.YearNumber)
					+ '-' + CONVERT(nvarchar( 2 ), Months.MonthNumber)
					+ '-' + CONVERT(nvarchar( 2 ), DayNumbers.DayNumber)
					, 120 
				)
			ELSE '17530101'
		END AS Date
	FROM
(SELECT  1  AS DayNumber
		UNION ALL SELECT  2  UNION ALL SELECT  3  UNION ALL
		SELECT  4  UNION ALL SELECT  5  UNION ALL SELECT  6 
		UNION ALL SELECT  7  UNION ALL SELECT  8  UNION ALL
		SELECT  9  UNION ALL SELECT  10  UNION ALL SELECT  11 
		UNION ALL SELECT  12  UNION ALL SELECT  13  UNION ALL
		SELECT  14  UNION ALL SELECT  15  UNION ALL SELECT  16 
		UNION ALL SELECT  17  UNION ALL SELECT  18  UNION ALL
		SELECT  19  UNION ALL SELECT  20  UNION ALL SELECT  21 
		UNION ALL SELECT  22  UNION ALL SELECT  23  UNION ALL
		SELECT  24  UNION ALL SELECT  25  UNION ALL SELECT  26 
		UNION ALL SELECT  27  UNION ALL SELECT  28  UNION ALL
		SELECT  29  UNION ALL SELECT  30  UNION ALL SELECT  31 
		) AS DayNumbers
		
	CROSS JOIN
		(SELECT  1  AS MonthNumber
		UNION ALL SELECT  2  UNION ALL SELECT  3  UNION ALL
		SELECT  4  UNION ALL SELECT  5  UNION ALL SELECT  6 
		UNION ALL SELECT  7  UNION ALL SELECT  8  UNION ALL
		SELECT  9  UNION ALL SELECT  10  UNION ALL SELECT  11 
		UNION ALL SELECT  12 
		) AS Months

	CROSS JOIN
		(SELECT  0  AS YearNumber
		UNION ALL SELECT  1  UNION ALL SELECT  2  UNION ALL
		SELECT  3  UNION ALL SELECT  4  UNION ALL SELECT  5 
		UNION ALL SELECT  6  UNION ALL SELECT  7  UNION ALL
		SELECT  8  UNION ALL SELECT  9  UNION ALL SELECT  10  UNION ALL
		SELECT  11  UNION ALL SELECT  12  UNION ALL SELECT  13  UNION ALL
		SELECT  14  UNION ALL SELECT  15  UNION ALL SELECT  16  UNION ALL
		SELECT  17  UNION ALL SELECT  18  UNION ALL SELECT  19  UNION ALL
		SELECT  20  UNION ALL SELECT  21  UNION ALL SELECT  22  UNION ALL
		SELECT  23  UNION ALL SELECT  24  UNION ALL SELECT  25  UNION ALL
		SELECT  26  UNION ALL SELECT  27  UNION ALL SELECT  28  UNION ALL
		SELECT  29  UNION ALL SELECT  30  UNION ALL SELECT  31  UNION ALL
		SELECT  32 
		) AS Years
	WHERE
		ISDATE(CONVERT(nvarchar( 4 ),  2008  + Years.YearNumber)
			+ '-' + CONVERT(nvarchar( 2 ), Months.MonthNumber)
			+ '-' + CONVERT(nvarchar( 2 ), DayNumbers.DayNumber)
		) =  1 
	) AS AllDates

INNER JOIN 
		(select TB.Nom, TB.Razm, TB.Date, SUM(TB.SumK) as S from TB
		WHERE TB.Date between @D_N and @D_KP AND	TB.Skl = @Skl
		GROUP BY TB.Nom, TB.Razm, TB.Date
) as DV ON DV.Date <= AllDates.Date

WHERE AllDates.Date BETWEEN @D_NP AND @D_KP

GROUP BY
	DV.Nom,DV.Razm,AllDates.Date

HAVING SUM(DV.S)>  0 

) as All_T
	
GROUP BY
	Nom,Razm

ORDER BY Nom,Razm

ну и результат

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
Nom       Razm      Дней
--------- --------- -----------
     7         C    154
     A         F    154
     A         I    154
     D         J    154
     E         E    154
     E         H    154
     H         G    66
     H         H    66
     M         F    154
     M         G    85
     O         F    154
    1H         F    154
    1H         G    154
    1I         F    154
    1K         F    41
    1L         E    154
    1L         I    154
    26         G    85
    2H         G    154
    2I         G    85
    31         1    154
    34         1    66
    37         1    154
    38         1    154
    39         1    10
    3A         1    16
    3F         1    16
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36610304
HoBTID
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Last1Cmen
Т.е. вам подошел вариант с INNER JOIN.
Если бы потребовались все товары и все размеры с начала периода, независимо от наличия продаж,
пришлось бы таблицу дат еще 2 раза соединить CROSS JOIN с таблицами товаров и размеров,
а потом LEFT JOIN с таблицей продаж.
...
Рейтинг: 0 / 0
SQL-щики нид хелп по вопросу количества дней в остатках
    #36610403
Last1Cmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HoBTID Last1Cmen
Т.е. вам подошел вариант с INNER JOIN.
Если бы потребовались все товары и все размеры с начала периода, независимо от наличия продаж,
пришлось бы таблицу дат еще 2 раза соединить CROSS JOIN с таблицами товаров и размеров,
а потом LEFT JOIN с таблицей продаж.

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

этот запрос отрабатывает без кэша (первый раз) порядка 3-5 минут а вот стандартный приблизительного объёма обрабатываемых записей почти в несколько раз дольше и приходилось делать через предварительный расчет ночью и потом уже по результирующему справочнику строить сам отчет

да... если кто вздумает таким образом и остатки получать то не советую, для этого подойдёт более приемлимый метод "остаток на период + движения по смещению даты внутри следующего периода"

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
select TB.Nom as Nom_ID,TB.Razm as Razm_ID,SUM(TB.Kvo) as Ost
from
(
select SP89 as Nom,SP90 as Razm, SUM(SP38) as Kvo 
from RG35
WHERE SP37 = @Skl AND PERIOD = @D_Period
GROUP BY SP89,SP90

UNION ALL

select SP89 as Nom,SP90 as Razm, SUM(CASE WHEN DEBKRED =  0  THEN SP38 ELSE - 1 *SP38 END) as Kvo 
from RA35 as TB_DV
	INNER JOIN
		(
			select JOURN.IDDOC as ID 
			from _1SJOURN as JOURN
			WHERE DATE_TIME_IDDOC between @D_NP AND @D_KP
		)
		as TB_D ON TB_D.ID = TB_DV.IDDOC
	
WHERE SP37 = @Skl
GROUP BY SP89,SP90
) as TB
GROUP BY TB.Nom,TB.Razm
HAVING SUM(TB.Kvo) <>  0 

это без флага в регистре "быстрая обработка движений" с ним можно без таблицы журнала работать напрямую с таблицей движений регистра
...
Рейтинг: 0 / 0
13 сообщений из 13, страница 1 из 1
Форумы / [игнор отключен] [закрыт для гостей] / SQL-щики нид хелп по вопросу количества дней в остатках
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]