我有一个包含以下列的表:ID、时间、值。
第一步:给定输入参数作为信号 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
最佳答案
EDITED 即时计算步数
。我一开始以为这是一场争论。
;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
?
关于sql - 如何优化SQL Server代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37035008/