数字范围内的数字循环

Numeric loop in an unrange of numbers

有没有办法为记录(在一个范围内)分配一个数字,当它结束时它从范围的第一个数字开始?

我目前有以下table:

id date first_number last_number start_number
1 01/01/2021 1 3 2
1 02/01/2021 1 3 2
1 03/01/2021 1 3 2
1 04/01/2021 1 3 2
1 05/01/2021 1 3 2
1 06/01/2021 1 3 2
1 07/01/2021 1 3 2
1 08/01/2021 1 3 2

我想根据start_range和last_range获取循环列中的赋值。 循环的开始必须是第一条记录的值(在示例 2 中)

id date first_number last_number start_number cycle
1 01/01/2021 1 4 2 2
1 02/01/2021 1 4 2 3
1 03/01/2021 1 4 2 4
1 04/01/2021 1 4 2 1
1 05/01/2021 1 4 2 2
1 06/01/2021 1 4 2 3
1 07/01/2021 1 4 2 4
1 08/01/2021 1 4 2 1

您可以使用 ROW_NUMBER 通过模运算符和一些加法实现此目的:

SELECT id,
       date,
       first_number,
       last_number,
       start_number,
       ISNULL(NULLIF((ROW_NUMBER() OVER (ORDER BY [date]) + start_number - first_number) % last_number,0),last_number)
FROM (VALUES(1,CONVERT(date,'01/01/2021',103),1,3,2),
            (1,CONVERT(date,'02/01/2021',103),1,3,2),
            (1,CONVERT(date,'03/01/2021',103),1,3,2),
            (1,CONVERT(date,'04/01/2021',103),1,3,2),
            (1,CONVERT(date,'05/01/2021',103),1,3,2),
            (1,CONVERT(date,'06/01/2021',103),1,3,2),
            (1,CONVERT(date,'07/01/2021',103),1,3,2),
            (1,CONVERT(date,'08/01/2021',103),1,3,2))V(id,date,first_number,last_number,start_number);

ISNULL/NULLIF 用于将 0 替换为最后一个值。

您 may/will 需要根据您对其他 id 值的要求添加 PARTITION BY 子句。

请注意,此处的结果与您的预期结果不符,因为在您的预期结果中 last_number 的值为 4,但在您的样本中具有值 3数据.

fiddle

 first_number+(start_number-first_number+row_number() over(order by date)-1)%(last_number+1-first_number) as cycle