我有一个遗留系统,它使用一组机器人(自动化流程)来收集放置在“收件箱”中的作业。该工作分发到“发件箱”供其他机器人处理。每个作业都由表中的一行表示。每行都有一个代表该框的id。每个作业都有一个优先级,表示输出机器人执行工作的顺序。
今天收件箱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
工作从“进入”转移到出去。优先级字段根据“输入”框的编号进行更新。
在上述情况中,总共有12个项目具有“10”优先级。项目是id:(1,2,3,4,5,6,7,8,9,15,16,17)。 12个项目,其中9个为“in”,3个为“out”,将分布在两个“out”框中。优先级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
答案 0 :(得分:0)
我能够在基于集合的时尚中实现这一目标。我在TSQL SQLServer2K8R2中使用了“ntile”。
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