我有一个包含列的表:Id,time,value。
第一步:给定输入参数作为信号id,开始时间和结束时间,我想首先提取具有信号id的行,并且时间在开始时间和结束时间之间。
第二:假设我在第一步中选择了100行。给定另一个输入参数max_num,我想进一步选择100行中的max_num样本,但是以统一的方式。例如,如果max_num设置为10,那么我将从100行中选择1,11,21,... 91行。
我不确定下面的存储过程是否最佳,如果您发现代码效率低下,请指出并给出一些建议。
create procedure data_selection
@sig_id bigint,
@start_time datetime2,
@end_time datetime2,
@max_num float
AS
BEGIN
declare @tot float
declare @step int
declare @selected table (id int primary key identity not null, Date datetime2, Value real)
// first step
insert into @selected (Date, Value) select Date, Value from Table
where Id = @sig_id
and Date > = @start_time and Date < = @end_time
order by Date
// second step
select @tot = count(1) from @selected
set @step = ceiling(@tot / @max_num)
select * from @selected
where id % @step = 1
END
答案 0 :(得分:2)
已编辑即时计算step
。我首先想到这是一个争论。
;with data as (
select row_number() over (order by [Date]) as rn, *
from Table
where Id = @sig_id and Date between @start_time and @end_time
), calc as (
select cast(ceiling(max(rn) / @max_num) as int) as step from data
)
select * from data cross apply calc as c
where (rn - 1) % step = 0 --and rn <= (@max_num - 1) * step + 1
或者我猜您可以按照您的identity
值进行排序/过滤:
;with calc as (select cast(ceiling(max(rn) / @max_num) as int) as step from @selected)
select * from @selected cross apply calc as c
where (id - 1) % step = 0 --and id <= (@max_num - 1) * step + 1
我认为,因为您使用step
将ceiling
四舍五入,所以您可以轻松找到行数少于@max_num
的情况。您可能想要向下舍入:case when floor(max(rn) / @max_num) = 0 then 1 else floor(max(rn) / @max_num) end as step
?