powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Подбор оптимального количества смен.
6 сообщений из 31, страница 2 из 2
Подбор оптимального количества смен.
    #39896207
Yaroslav85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
982183

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

ну задача стояла как раз четко: "подсказать сколько и каких смен из действующих оптимально нужно"
Но кадровик сам исходя из подсказки назначает операторов, и не факт что в результате назначит так как ему подсказала программа
...
Рейтинг: 0 / 0
Подбор оптимального количества смен.
    #39896216
Yaroslav85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
982183
+ в качестве входной информации, наверное, стоит использовать не, рассчитанное ранее, требуемое наличие персонала,
а фактическую нагрузку (например - число звонков/обращений и/или человекочасы консультаций

этот блок уже реализован, и рассчитанное ранее, требуемое наличие персонала/час - рассчитано как раз на основании исторических данных.
...
Рейтинг: 0 / 0
Подбор оптимального количества смен.
    #39896276
Александр Спелицин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yaroslav85

ну задача стояла как раз четко: "подсказать сколько и каких смен из действующих оптимально нужно"
Но кадровик сам исходя из подсказки назначает операторов, и не факт что в результате назначит так как ему подсказала программа

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

PS. Если зафиксировать, что есть определенный момент времени, через который ни одна из смен не переходит (в текущих данных это 08:00 утра), то отпадает сценарий с переходом смены на следующий день. Это немного упростит задачу.
...
Рейтинг: 0 / 0
Подбор оптимального количества смен.
    #39896381
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Yaroslav85
court, заметил, что в коде есть четкая проверка на 7-ю смену.
а можно как-то сделать проверку динамическую?
а то вдруг добавят другую ночную смену, или эту поменяют

да, нужно даже :)
просто с этой "ночной сменой" всё несколько "замучено"

Если считаем, что "ночная смена" - это в ночь, на след.день, то непонятно как определять 0-8ч. первого дня
Если считаем, что "ночная смена" - это в ночь, на этот день, то та же проблема с посл.часами 7-го дня ...

Вообщем я ещё добавил в #OperatorsNeed одну запись (это значение для 23ч 7-го дня)
Код: sql
1.
insert into #OperatorsNeed values (8,0,2)



и тогда как-то так
Код: sql
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.
declare @t table ([DayOfWeek] int, [Hour] int, idSmeny int) 
declare @DayOfWeek int, @Hour int, @OpNeed int, @CurrOp int
declare opn cursor local forward_only
for
	select [DayOfWeek],[Hour],[OpNeed] from #OperatorsNeed order by 1, 2

open opn;

fetch next from opn into @DayOfWeek, @Hour, @OpNeed  

while @@FETCH_STATUS = 0 
begin
	--	сколько "на сейчас" в работе
	set @CurrOp = isnull((
		select
			count(*)
		from @t t inner join #Smeny s on t.idSmeny = s.id
		where	(t.[DayOfWeek] = @DayOfWeek and (@Hour between s.hFrom and s.hTo or @Hour between s.hFrom and s.hToCorrect or @Hour between s.hFromCorrect and s.hTo))
			), 0);

	--	
	if @CurrOp < @OpNeed
	begin
		;with a as (
				--	самая поздняя смена для @Hour		
				select top 1
					id
				from
					(select 
						s.id
						,case when @Hour > s.hFrom then s.hFrom else s.hFromCorrect end as hFrom
						,24 - s.hFrom + s.hTo as Duration
					from #Smeny s
					where s.hFrom > s.hTo and (@Hour >= s.hFrom or @Hour < s.hTo)
				
					union all
				
					select 
						s.id
						,s.hFrom 
						,s.hTo - s.hFrom
					from #Smeny s
					where s.hFrom < s.hTo and s.hFrom<=@Hour) t
				order by hFrom desc, Duration),
			b as ( 
				select 1 as n union all select n+1 from b where n < @OpNeed - @CurrOp)

		insert into @t ([DayOfWeek], [Hour], idSmeny)
		select @DayOfWeek, @Hour, a.id
		from a cross join b

	end

	fetch next from opn into @DayOfWeek, @Hour, @OpNeed
end

select [DayOfWeek], idSmeny, count(*) as NeedSmenCount from @t group by [DayOfWeek], idSmeny order by 1, 3, 2

close opn;  
deallocate opn;



DayOfWeekidSmenyNeedSmenCount11217215314425227321724153513753183414453475417441255257551754136516626166766415751773714748872

Код: sql
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.
--	Проверка ("1. посчитанное к-во необходимого к-ва операторов на каждый час:")
;with cte as (
	select 0 as h union all select h+1 from cte where h<23),
cte1 as (
	select 
		t.[DayOfWeek]
		,t.idSmeny
		,s.hFrom
		,s.hTo
	from @t t inner join #Smeny s on t.idSmeny = s.id
	where s.hFrom < hTo

	union all

	select 
		t.[DayOfWeek]-1
		,t.idSmeny
		,s.hFrom
		,s.hToCorrect
	from @t t inner join #Smeny s on t.idSmeny = s.id
	where s.hFrom > hTo

	union all

	select 
		t.[DayOfWeek]
		,t.idSmeny
		,s.hFromCorrect
		,s.hTo
	from @t t inner join #Smeny s on t.idSmeny = s.id
	where s.hFrom > hTo),
cte2 as (
	select
		cte1.[DayOfWeek]
		,cte.h as [Hour]
		,count(*) as OpFact
		,string_agg(cast(idSmeny as varchar),',') as allSmeny
	from cte inner join cte1 on cte.h between cte1.hFrom and cte1.hTo
	group by
		cte1.[DayOfWeek]
		,cte.h)

select 
	cte2.[DayOfWeek]
	,cte2.[Hour]
	,cte2.allSmeny
	,cte2.OpFact
	,opn.OpNeed
	,delta = cte2.OpFact - opn.OpNeed
from cte2 inner join #OperatorsNeed opn on cte2.[DayOfWeek] = opn.[DayOfWeek] and cte2.[Hour]=opn.[Hour]
order by 1,2


DayOfWeekHourallSmenyOpFactOpNeeddelta107,7211117,7211127,7211137,7211147,7211157,7211167,7211177,7220187,7,1,1440191,1,4,4,4,46601104,4,4,4,1,1,5,5,59901115,5,5,1,1,4,4,4,49901124,4,4,4,1,1,5,5,59721135,5,5,1,1,4,4,4,49721144,4,4,4,1,1,5,5,59631155,5,5,1,1,4,4,4,49541164,4,4,4,1,1,5,5,59541175,5,5,1,1,4,4,4,49631184,4,4,4,5,5,57611195,5,5,4,4,4,47521204,4,4,4,5,5,5,7,7,710551217,7,7,5,5,5,4,4,4,410461225,5,5,7,7,76331237,7,7321207,7,7312217,7,7312227,7,7312237,7,7312247,7,7312257,7,7312267,7,7312277,7,7330287,7,7,1,1,1,1,1,1,110100291,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4222202104,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,1,1,1,1,1,1,1242402111,1,1,1,1,1,1,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4242402124,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,1,1,1,1,1,1,1242222131,1,1,1,1,1,1,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4241952144,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,1,1,1,1,1,1,1241952151,1,1,1,1,1,1,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4241862164,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,1,1,1,1,1,1,1241772171,1,1,1,1,1,1,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,42414102184,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4171342194,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4171252204,4,4,4,4,4,4,4,4,4,4,4,4,5,5,4,4,7,7,7,7,7229132217,7,7,7,7,4,4,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4228142225,5,7,7,7,7,77432237,7,7,7,7523307,7,7,7,7514317,7,7,7,7514327,7,7,7,7514337,7,7,7,7514347,7,7,7,7514357,7,7,7,7514367,7,7,7,7514377,7,7,7,7550387,7,7,7,7,1,1,1,1,1,1,1,113130391,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4222203104,4,4,4,4,4,4,4,4,4,4,4,4,4,5,1,1,1,1,1,1,1,1232303111,1,1,1,1,1,1,1,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4232213124,4,4,4,4,4,4,4,4,4,4,4,4,4,5,1,1,1,1,1,1,1,1231943131,1,1,1,1,1,1,1,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4231763144,4,4,4,4,4,4,4,4,4,4,4,4,4,5,1,1,1,1,1,1,1,1231763151,1,1,1,1,1,1,1,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4231673164,4,4,4,4,4,4,4,4,4,4,4,4,4,5,1,1,1,1,1,1,1,1231583171,1,1,1,1,1,1,1,5,4,4,4,4,4,4,4,4,4,4,4,4,4,42313103184,4,4,4,4,4,4,4,4,4,4,4,4,4,5151143195,4,4,4,4,4,4,4,4,4,4,4,4,4,4151233204,4,4,4,4,4,4,4,4,4,4,4,4,4,5,7,7,7,7,7209113217,7,7,7,7,5,4,4,4,4,4,4,4,4,4,4,4,4,4,4207133225,7,7,7,7,76423237,7,7,7,7523407,7,7,7,7514417,7,7,7,7514427,7,7,7,7514437,7,7,7,7514447,7,7,7,7514457,7,7,7,7514467,7,7,7,7523477,7,7,7,7550487,7,7,7,7,1,1,1,1,1,1,112120491,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4191904104,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,5,5,5222204115,5,5,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4222114124,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,5,5,5221934135,5,5,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4221754144,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,5,5,5221754155,5,5,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4221664164,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,5,5,5221574175,5,5,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4221484184,4,4,4,4,4,4,4,4,4,4,4,5,5,5151234195,5,5,4,4,4,4,4,4,4,4,4,4,4,4151144204,4,4,4,4,4,4,4,4,4,4,4,5,5,5,7,7,7,7,7209114217,7,7,7,7,5,5,5,4,4,4,4,4,4,4,4,4,4,4,4207134225,5,5,7,7,7,7,78444237,7,7,7,7523507,7,7,7,7514517,7,7,7,7514527,7,7,7,7514537,7,7,7,7514547,7,7,7,7514557,7,7,7,7514567,7,7,7,7523577,7,7,7,7550587,7,7,7,7,1,1,1,1,1,1,112120591,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4202005104,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,5,5222205115,5,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4222205124,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,5,5222025135,5,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4222025144,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,5,5221935155,5,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4221755164,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,1,5,5221755175,5,1,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4221395184,4,4,4,4,4,4,4,4,4,4,4,4,5,5151325195,5,4,4,4,4,4,4,4,4,4,4,4,4,4151235204,4,4,4,4,4,4,4,4,4,4,4,4,5,5,7,7,7,7,7,72110115217,7,7,7,7,7,5,5,4,4,4,4,4,4,4,4,4,4,4,4,4218135225,5,7,7,7,7,7,78535237,7,7,7,7,7633607,7,7,7,7,7615617,7,7,7,7,7615627,7,7,7,7,7615637,7,7,7,7,7615647,7,7,7,7,7615657,7,7,7,7,7615667,7,7,7,7,7624677,7,7,7,7,7660687,7,7,7,7,7,1,1,1,1,1,112120691,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4212106104,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,5222206115,6,6,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4242406124,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,6,6,5242046135,6,6,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4241776144,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,6,6,5241686155,6,6,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4241776164,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1,1,1,1,1,1,6,6,5241686175,6,6,1,1,1,1,1,1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,42413116184,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,6,5181266195,6,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4181086204,4,4,4,4,4,4,4,4,4,4,4,4,4,4,6,7,7,7,6,5217146215,6,7,7,7,6,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4217146226,7,7,7,6,56516236,7,7,7,6532707,7,7321717,7,7312727,7,7312737,7,7312747,7,7312757,7,7312767,7,7312777,7,7330787,7,7,1,1,1,1770791,1,1,1,4,4,4,4,4,4,4,4121207104,4,4,4,4,4,4,4,1,1,1,1,5131307115,1,1,1,1,4,4,4,4,4,4,4,4131307124,4,4,4,4,4,4,4,1,1,1,1,5131127135,1,1,1,1,4,4,4,4,4,4,4,413947144,4,4,4,4,4,4,4,1,1,1,1,513857155,1,1,1,1,4,4,4,4,4,4,4,413857164,4,4,4,4,4,4,4,1,1,1,1,513857175,1,1,1,1,4,4,4,4,4,4,4,413767184,4,4,4,4,4,4,4,59727195,4,4,4,4,4,4,4,49637204,4,4,4,4,4,4,4,5,7,711567217,7,5,4,4,4,4,4,4,4,411567225,7,73307237,7220807,7220
...
Рейтинг: 0 / 0
Подбор оптимального количества смен.
    #39896387
Фотография court
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и ещё ...
Если ночная смена только одна, то, можно сделать такой же прогон по всем дням/часам, только в "обратном" направлении.
Т.е. от 7 день, 23ч. к 1-й день 0ч.

И, таким образом, получить два набора смен для дня.
И уже из них, выбирать лучший на конкретный день.
При условии, что "ночная смена" единственная, - они получаться "взаимозаменяемые"
...
Рейтинг: 0 / 0
Подбор оптимального количества смен.
    #39896949
Yaroslav85
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
court, спасибо огромное.
Пошел разбираться с решением :)
...
Рейтинг: 0 / 0
6 сообщений из 31, страница 2 из 2
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Подбор оптимального количества смен.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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