简体   繁体   中英

SQL - Generate Round robin number on insert

I am deploying an existing bespoke windows service (C#) multiple instances that will reads from a single queue table.

The queue is based on the below simple SQL table.

Record-Id (int auto id)

Added-Date (Date)

Added-By (Text)

Data-To-be-Processed (Text)

**Pool-Number (int)**

How would I create a round robin sequence number for each insert given a max pool size? here I use a pool size of 3 (This can be hard coded). eg

1 | 31/10/2014 | DATA | Pool 1

2 | 31/10/2014 | DATA | Pool 2

3 | 31/10/2014 | DATA | Pool 3

4 | 31/10/2014 | DATA | Pool 1

5 | 31/10/2014 | DATA | Pool 2

6 | 31/10/2014 | DATA | Pool 3

7 | 31/10/2014 | DATA | Pool 1

I have thought about using a Sequence table and increment it on each insert and reset it to 1 when it gets to the max pool size eg

TbSeq

  dbSeq (int) (Will contain 1-3 depending last insert)

Is there a better way to do this?

If you can use the RecordId as an aid, then you could use Modulo ( % )

select *, 1+((RecordId-1)%3) as Pool
from t

rextester demo: http://rextester.com/WNEIQM50851

returns:

+----------+------------+-------------------+------+
| RecordId | AddedDate  | DataToBeProcessed | Pool |
+----------+------------+-------------------+------+
|        1 | 2014-10-31 | DATA              |    1 |
|        2 | 2014-10-31 | DATA              |    2 |
|        3 | 2014-10-31 | DATA              |    3 |
|        4 | 2014-10-31 | DATA              |    1 |
|        5 | 2014-10-31 | DATA              |    2 |
|        6 | 2014-10-31 | DATA              |    3 |
|        7 | 2014-10-31 | DATA              |    1 |
+----------+------------+-------------------+------+

You could add this as a computed column (persisted optional, but recommended)

alter table t
  add Pool as (1+((RecordId-1)%3)) persisted;

I wouldn't depend on the RecordId per se . It might have gaps. The simplest way to do a real round-robin is to use row_number() and modulo arithmetic:

select 1 + (row_number() over (order by id) - 1) % 3 as poolnum
from t;

If you know that RecordId has no gaps, then you can use that instead. Using RecordId is more efficient, because you can do the full calculation within one row, and even add a computed column:

alter table t add poolnum as (1 + (row_number() over (order by id) - 1) % 3)

You can use SECQUENCE as:

CREATE TABLE MyTable (
    Record_Id INT IDENTITY(1,1), Added_Date DATE,
    Added_By VARCHAR(50), Data_To_be_Processed VARCHAR(50), Pool_Number INT);
GO    
CREATE SEQUENCE Pool
AS INT
START WITH 1
MINVALUE 1
MAXVALUE 3
CYCLE
GO

INSERT INTO MyTable VALUES
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool),
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool),
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool),
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool),
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool),
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool),
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool),
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool),
('2014-10-31', 'DATA', 'Pool', NEXT VALUE FOR Pool);

SELECT *
FROM MyTable;

Result:

+-----------+---------------------+----------+----------------------+-------------+
| Record_Id |     Added_Date      | Added_By | Data_To_be_Processed | Pool_Number |
+-----------+---------------------+----------+----------------------+-------------+
|         1 | 31.10.2014 00:00:00 | DATA     | Pool                 |           1 |
|         2 | 31.10.2014 00:00:00 | DATA     | Pool                 |           2 |
|         3 | 31.10.2014 00:00:00 | DATA     | Pool                 |           3 |
|         4 | 31.10.2014 00:00:00 | DATA     | Pool                 |           1 |
|         5 | 31.10.2014 00:00:00 | DATA     | Pool                 |           2 |
|         6 | 31.10.2014 00:00:00 | DATA     | Pool                 |           3 |
|         7 | 31.10.2014 00:00:00 | DATA     | Pool                 |           1 |
|         8 | 31.10.2014 00:00:00 | DATA     | Pool                 |           2 |
|         9 | 31.10.2014 00:00:00 | DATA     | Pool                 |           3 |
+-----------+---------------------+----------+----------------------+-------------+

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM