在一组记录 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 显示不同的序列范围和起点。
案例:
用户需要 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 显示不同的序列范围和起点。