数字范围内的数字循环
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
数据.
first_number+(start_number-first_number+row_number() over(order by date)-1)%(last_number+1-first_number) as cycle
有没有办法为记录(在一个范围内)分配一个数字,当它结束时它从范围的第一个数字开始?
我目前有以下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
数据.
first_number+(start_number-first_number+row_number() over(order by date)-1)%(last_number+1-first_number) as cycle