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

Posted

技术标签:

【中文标题】SQL 检索特定日期时间的历史传感器值【英文标题】:SQL Retrieve historical sensor values at specific date times 【发布时间】:2009-01-17 21:12:15 【问题描述】:

我有一个数据库,该数据库的血管压力每 30 秒变化一次。我希望能够检索过去几天中特定时间的录音。我无法将其作为存储过程或视图基于服务器——我只有读取权限。我创建了一个过去 17 天的例程,但我希望它能够提供几个月的数据。我猜想只是从 c# 应用程序重复调用,但这似乎比我现在使用的方法效率低。有没有人有什么建议。

布拉德

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)

【问题讨论】:

【参考方案1】:

不要使用循环......我认为你也没有。你看过 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

或者,您可以将日期归零,然后使用 datediff 函数比较您的目标时间和您正在寻找的时间之间的分钟数。

其中 ABS(datediff(mi,convert(nvarchar(10),getdate(),8),'10:00PM'))=60 这将为您获取在晚上 10:00 后 60 分钟内发生的所有记录,因此从晚上 9 点到 11 点

【讨论】:

【参考方案2】:

我见过很多将 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

人们可以轻松地将其适应一天中的几个关键时间,或一系列时间等等......

编辑:

正如 cmets 对此答案所述,对数据库结构的更改也将在这里受益。具有 DATE 字段和 TIME 字段。通常是多余的,但在这种情况下可能是有益的。

【讨论】:

@Dems:该 TSQL 代码的唯一问题是与 [WideHistory] ​​的比较不是 S'argable,因此无法使用索引。 确实,它类似于索引 VARCHAR 字段,然后使用中间 3 个字符连接。出于这个原因,我已经开始在我的表中存储一个 DATE 字段和一个 TIME 字段。甚至 (Date then Time) 的 INDEX 也会带来一些好处,如果需要的话,我可以创建 (Time then Date) INDEX...【参考方案3】:

您不能通过将日期时间转换为 unixtime 数字并对其进行修改以提供一天中的时间来更有效地做到这一点。

where 子句会根据您想要的日期范围对其进行过滤,然后 mod 技巧会丢弃所有不在您想要的时间的记录。

然后您可以查询一次,而不是每天查询一次。

【讨论】:

以上是关于SQL 检索特定日期时间的历史传感器值的主要内容,如果未能解决你的问题,请参考以下文章

ORACLE PL/SQL - 使用 SYSDATE 检索特定日期的数据时出现检索问题

SQL:如何最好地查询历史表以创建特定日期的快照概览

从前一个日期检索特定字段

Hive SQL - 检索日期范围中存在的列的不同值

SQL Server 导入导出向导 - 日期时间错误 - 特定值

使用ajax codeigniter php根据日期检索数据库值