SQL 中的循环票分配有活动票的限制?

Round Robin Ticket Assignment in SQL with limit of active tickets?

我必须以循环方式将工单分配给员工,阈值是 5 张工单给员工。

员工的有效工单不应超过 5 张。在分配门票时,我们应该检查他的桶中的活动门票。

例子 我有一张票 table

          Table Tickets
       
          | TicketId | AssignedTo     |
          | -------- | -------------- |
          | 1        |                | 
          | 2        |                |
          | 3        |                | 
          | 4        |                |
          | 5        |                | 
          | 6        |                |            
          | 7        |                | 
          | 8        |                | 
          | 9        |                | 
          | 10       |                |            
          | 11       |                | 
          | 12       |                |    

员工table

          | EmployeeId | ActiveTickets     |
          | --------   | --------------    |
          | 123        |     4             | 
          | 124        |     0             |
          | 125        |     3             | 
          | 126        |     1             |
          | 127        |     1             |     

由于员工 123 在分配工单时有 4 张活动工单,他应该只分配工单中的一张工单 table。

结果应该如下所示

          Table Tickets
       
          | TicketId | AssignedTo     |
          | -------- | -------------- |
          | 1        |    123         | 
          | 2        |    124         | 
          | 3        |    125         |  
          | 4        |    126         | 
          | 5        |    127         | 
          | 6        |    124         |          
          | 7        |    125         | 
          | 8        |    126         |  
          | 9        |    127         | 
          | 10       |    124         |         
          | 11       |    126         | 
          | 12       |    127         | 

使用下面的查询,我能够实现工单的循环分配,但不确定如何设置活动工单的阈值。

       WITH    с AS
    (
    SELECT  *, ROW_NUMBER() OVER ORDER BY (TicketId) AS rn
    FROM    Tickets
    ),
    s AS
    SELECT  *,
            ROW_NUMBER() OVER ORDER BY (EmployeeId) AS rn
    FROM    Employee
    )
    SELECT  c.*, s.*
    FROM    с
    JOIN    s
    ON      s.rn =
    (с.rn - 1) %
    (
    SELECT  COUNT(*)
    FROM    Employee
    ) + 1         

您可以使用递归 cte 创建员工的所有“免费实例”的队列。获取新分配的查询:

with cte as (
   select e.EmployeeId, count(t.TicketId) n
   from Empl e
   left join Tickets t  on t.AssignedTo = e.EmployeeId 
   group by e.EmployeeId
   having count(t.TicketId) < 5
   
   union all
   
   select EmployeeId, n+1
   from cte
   where n < 4
), EQueue as (
   select EmployeeId, n, row_number() over(order by n, EmployeeId) rn
   from cte
), TQueue as (
   select TicketId, row_number() over(order by TicketId) rn
   from Tickets
   where AssignedTo is null
)
select t.TicketId, e.EmployeeId AssignedTo
from EQueue e
join TQueue t on e.rn = t.rn;

db<>fiddle