在一组记录 oracle sql 中重复查找 table 中的序列

repeat a sequence from a lookup table across a set number of records oracle sql

案例:

用户需要 select 特定时间段的开始和结束日期,他们还需要 select 序列以及他们希望在序列中的何处开始序列循环(序列存储在查找中 table...存储序列的示例显示在下面的序列查找下的示例中)。

user input parameters:
 start date : 01-jan-2021 
 end date : 14-jan-2021
 sequence_name : 1-5
 start sequence at : 4

用户输入参数后,系统会

列出 2021 年 1 月 1 日至 2021 年 1 月 14 日之间的所有日期 - 如下例所示,然后它将开始将序列映射到以输入的序列号开始的日期,在本例中为 4 (如下例所示)

当系统到达序列的末尾(在本例中末尾为 5)时,它将从 1 重新开始序列,因为这是查找中序列的开始。

在下面的示例图片中,它显示了结果的样子。

感谢您的帮助!

我更喜欢用 sql 写,但如果不能用 sql 写,那么 plsql 也可以。

你还没有真正解释你是如何从你的 'sequence name' 得到一个值范围的,所以我假设你已经知道了那部分,并且将从一个日期范围和一个序列范围开始工作,为简单起见,可以将其作为 CTE 提供:

with input (start_date, end_date, start_seq, end_seq, start_at) as (
  select date '2021-01-01', date '2021-01-14', 1, 5, 4 from dual
)
select * from input

您用 Oracle 11g 标记了问题。如果是 11gR2,那么您可以使用递归 CTE 从该模拟输入数据生成结果:

with input (start_date, end_date, start_seq, end_seq, start_at) as (
  select date '2021-01-01', date '2021-01-14', 1, 5, 4 from dual
),
rcte (dt, seq, end_date, start_seq, end_seq) as (
  select start_date, start_at, end_date, start_seq, end_seq
  from input
  union all
  select dt + 1, case when seq = end_seq then start_seq else seq + 1 end,
    end_date, start_seq, end_seq
  from rcte
  where dt < end_date
)
select dt, seq
from rcte
order by dt;

主播成员使用开始日期和起始值,并保留以后需要的其他信息。递归成员递增两者,将 seq 值包装在该范围的顶部。给出结果:

DT        | SEQ
:-------- | --:
01-JAN-21 |   4
02-JAN-21 |   5
03-JAN-21 |   1
04-JAN-21 |   2
05-JAN-21 |   3
06-JAN-21 |   4
07-JAN-21 |   5
08-JAN-21 |   1
09-JAN-21 |   2
10-JAN-21 |   3
11-JAN-21 |   4
12-JAN-21 |   5
13-JAN-21 |   1
14-JAN-21 |   2

在早期版本中,或者如果您愿意,您可以使用分层查询,它看起来更短,但我认为它不太直观:

with input (start_date, end_date, start_seq, end_seq, start_at) as (
  select date '2021-01-01', date '2021-01-14', 1, 5, 4 from dual
)
select start_date + level - 1 as dt,
  mod(level - 1 + start_at - start_seq, end_seq - start_seq + 1) + start_seq as seq
from input
connect by level <= end_date - start_date + 1
order by dt;

db<>fiddle 显示两种方法。

第二个 db<>fiddle 显示不同的序列范围和起点。