Распределите работу равномерно в зависимости от значения поля - PullRequest
0 голосов
/ 07 сентября 2011

У меня есть устаревшая система, которая использует набор роботов (автоматизированных процессов) для сбора заданий, которые помещаются в «входящие». Работа распределяется в «исходящие» для обработки другими роботами. Каждое задание представлено строкой в ​​таблице. Каждая строка имеет идентификатор, который представляет поле. Каждое задание имеет приоритет, который представляет порядок, в котором выходной робот будет выполнять задание.

Сегодня задания в папке «Входящие 1» распределяются равномерно по каждому из исходящих с помощью курсора, затем папка «2» обрабатывается снова с помощью курсора и т. Д. Через каждую папку «Входящие» приоритет не учитывается, поэтому один из «Исходящих» может иметь много высокого приоритета и другие исходящие сообщения не будут иметь высокоприоритетных заданий.

Я хотел бы найти способ устранения курсора и распределения заданий на основе количества заданий в папке «Исходящие», которые имеют такой же приоритет, что и папки «Входящие».

    Start
id        box_name  priority
1         in_10         0
2         in_10         0
3         in_10         0
4         in_10         0
5         in_10         0
6         in_10         0
7         in_10         0
8         in_10         0
9         in_10         0
10        in_25         0
11        in_25         0
12        in_25         0
13        in_25         0
14        in_25         0
15        out_1         10
16        out_2         10
17        out_2         10
18        out_2         25

Работа перемещена из "в" в. Поле приоритета обновляется в зависимости от номера поля «in».

В приведенном выше случае всего 12 элементов имеют приоритет «10». Элементы являются id: (1,2,3,4,5,6,7,8,9,15,16,17). 12 элементов, 9 из которых «в» и 3 «вне», будут распределены по двум «вне» коробки. Целевое количество элементов в исходящем блоке для приоритета 10 равно 6. Поскольку в блоке 1 в настоящее время есть один элемент, мы переместим 5 элементов. В коробке 2 есть 2 предмета, поэтому мы переместим 4 предмета.

Логика повторяется для приоритета 25

AFTER
id        box_name  priority
1         out_1         10
2         out_1         10
3         out_1         10
4         out_1         10
5         out_1         10
6         out_2         10
7         out_2         10
8         out_2         10
9         out_2         10
10        out_1         25
11        out_1         25
12        out_1         25
13        out_2         25
14        out_2         25
15        out_1         10
16        out_2         10
17        out_2         10
18        out_2         25

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

declare @start table(id int identity(1,1), box_name char(10), priority int)
Insert @start (box_name, priority)
VALUES
('in',         10),
('in',         10),
('in',         10),
('in',         10),
('in',         10),
('in',         10),
('in',         10),
('in',         10),
('in',         10),
('in',         25),
('in',         25),
('in',         25),
('in',         25),
('in',         25),
('out_1',         10),
('out_2',         10),
('out_2',         10),
('out_2',         25)

--select * from @start
select distinct

[box_name], [priority]
,COUNT([box_name]) OVER (PARTITION BY [box_name],[priority] ) AS [count_source_by_priority]
,count([priority])OVER (PARTITION BY [priority] ) AS [Total_by_priority]
from @start

1 Ответ

0 голосов
/ 22 сентября 2011

Мне удалось сделать это в наборе, основанном на моде.Я использовал "ntile" в TSQL SQLServer2K8R2.

declare @start table(id int identity(1,1), box_name char(10), priority int) 
Insert @start (box_name, priority) 
VALUES 
('in',         10), 
('in',         10), 
('in',         10), 
('in',         10), 
('in',         10), 
('in',         10), 
('in',         10), 
('in',         10), 
('in',         10), 
('in',         25), 
('in',         25), 
('in',         25), 
('in',         25), 
('in',         25), 
('out_1',         10), 
('out_2',         10), 
('out_2',         10), 
('out_2',         25) 

--select * from @start
--start of solution

--create a work table to hold the "out" box names
declare @out_box table (ob_id int identity(1,1), ob_name varchar(5))
--fill the work table
Insert @out_box
Select distinct box_name from @start where box_name != 'in'
--show the work table
select * from @out_box
--calculate the number of "out"boxes
declare @#ofOutBoxes int
select @#ofOutBoxes = MAX(ob_id) from @out_box
--show the calculated value
select @#ofOutBoxes
--reset all the work to "in" box
update @start set box_name = 'in' 
--create a table to hold the work with the newly associated "out" box
declare @start1 table(s1_id int identity(1,1), s1_s_id int, s1_box_name char(10), s1_priority int, s1_ntilevalue int, s1_targetRobot varchar(5)) 
Insert @start1 (s1_s_id,s1_box_name, s1_priority, s1_ntilevalue)
Select
id, box_name,priority,
NTILE(@#ofOutBoxes) OVER(PARTITION BY priority ORDER BY priority) AS 'ntilevalue' 
from @start 
--show the data
select * from @start1

---join the @start1 table and the @out_box table on the ntile value
UPDATE @Start1
SET s1_targetRobot = ob_name
from @start1 
inner join 
 @out_box 
 on s1_ntilevalue = ob_id

Select * from @Start1
--Use the joined table to update the @start table
UPDATE @Start
SET box_name = s1_targetRobot
FROM @Start
inner join 
 @Start1
 on id = s1_s_id

 Select * from @Start order by priority
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...