我有一个数据库,其容器压力每30秒趋势一次。我希望能够在过去的几天内在特定时间检索录音。我无法将其作为存储过程或视图在服务器上 - 我只有读访问权限。我创建了一个过去17天工作的例程,但我希望能够提供几个月的数据。我可以猜测只是从c#app重复调用,但这似乎比我现在使用的方法效率更低。有没有人有任何建议。
布拉德
declare @DeadBand DateTime
declare @EndDate DateTime
declare @End varchar(50)
declare @Start varchar(50)
declare @Temp varchar(50)
declare @NumberDays int
declare @dec int
declare @InnerSqlQry as varchar(8000)
declare @SqlQry as varchar(8000)
SET @NumberDays = 5
SET @dec = @NumberDays
SET @Start = CONVERT(Varchar(30),dateadd(dd,-@NumberDays,GetDate()))
SET @End = CONVERT(Varchar(30),GetDate())
SET @DeadBand= + CONVERT(Varchar(30),dateadd(ss,90,@Start))
SET @Width = + CONVERT(Varchar(30),dateadd(ss,90,@Start))
WHILE (@dec >= 1)
BEGIN
set @InnerSqlQry = ' Select DateTime,ACMKWHYTD_1 From WideHistory Where Datetime >='''+convert(varchar(30), @Start ,120) +''' AND Datetime <= '''+convert(varchar(30),@DeadBand,120) +''' and wwResolution =60000 and wwRetrievalMode = "cyclic" '
if(@dec = 1)
begin
set @SqlQry = @SqlQry+ N' Select top 1 * from openquery(INSQL,''' + REPLACE(@InnerSqlQry, '''', '''''') + ''' )'
end
if((@dec > 1) and (@dec < @NumberDays))
begin
set @SqlQry = @SqlQry+ N' Select top 1 * from openquery(INSQL,''' + REPLACE(@InnerSqlQry, '''', '''''') + ''' ) union '
end
if(@dec = @NumberDays)
begin
set @SqlQry = N' Select top 1 * from openquery(INSQL,''' + REPLACE(@InnerSqlQry, '''', '''''') + ''' ) union '
end
set @dec = @dec - 1
SET @Start = CONVERT(Varchar(30),dateadd(dd,-@dec,GetDate()))
SET @DeadBand= + CONVERT(Varchar(30),dateadd(ss,90,@Start))
END
print(@sqlQry)
exec(@sqlQry)
答案 0 :(得分:2)
不要使用循环......我认为你也没有。你看过DatePart了吗?
例如,此查询将获取12:30发生的开始日期和停止日期之间的所有记录。
Select DateTime,ACMKWHYTD_1 From WideHistory
WHERE DateTime BETWEEN @Start AND @DeadEnd
AND DATEPART(hh,datetime) =12 AND DatePart(mi,datetime)=30
Alternativley你可以将日期归零,然后使用datediff函数来比较你的目标时间和你所寻找的例子之间的分钟数。
其中ABS(datediff(mi,convert(nvarchar(10),getdate(),8),'10:00 PM'))= 60这将为您提供在晚上10:00的60分钟内发生的所有记录。晚上9-11点
答案 1 :(得分:0)
你不能通过将日期时间转换为unixtime数字并对其进行修改以便为你提供时间来更有效地做到这一点。
where子句会根据你想要的日期范围对其进行过滤,然后mod技巧会丢弃所有不在你想要的时间的记录。
然后您可以每天查询一次而不是一次。
答案 2 :(得分:0)
我已经看到了将DATETIME转换为“只是一个时间”的一些技巧。事实上我工作的时间花了很多时间才找到最快的。人们似乎忘记了“最短代码”并不总是最快,并且通常包含隐藏的隐式类型转换。我们提出的最快的是......
DATEADD(DAY,DATEDIFF(MINUTE,0,),0)
我提到它的原因是,一旦你有时间组件,一切都变得更容易,并允许更容易的代码更改,以满足不同的需求。
DECLARE
@start_date DATETIME,
@end_date DATETIME,
@chosen_time DATETIME
SELECT
@start_date = '2009 Jan 05 00:00',
@end_date = '2009 Jan 12 00:00',
@chosen_time = '1900 Jan 01 17:30' -- '1900 Jan 01' is day 0
SELECT
<whatever>
FROM
WideHistory
WHERE
[WideHistory].DateTime >= @start_date
AND [WideHistory].DateTime < @end_date
AND DATEADD(DAY, DATEDIFF(MINUTE, 0, [WideHistory].DateTime), 0) = @chosen_time
人们可以很容易地将其适应一天中的几个关键时刻,或者一系列时间等等......
编辑:
正如本回答的评论中所提到的,对数据库结构的更改也会在此受益。有一个DATE字段和一个TIME字段。通常是多余的,但在这种情况下可能是有益的。