SQL在特定日期时检索历史传感器值

时间:2009-01-17 21:12:16

标签: c# sql sql-server

我有一个数据库,其容器压力每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)

3 个答案:

答案 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字段。通常是多余的,但在这种情况下可能是有益的。