SQL Получить исторические значения датчика в определенное время - PullRequest
1 голос
/ 18 января 2009

У меня есть база данных, в которой давление в сосуде изменяется каждые 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)

Ответы [ 3 ]

2 голосов
/ 18 января 2009

Не используйте цикл ... и я не думаю, что вы тоже. Вы смотрели на 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), '22:00 PM')) = 60 Это позволит вам получить все записи, которые произошли в течение 60 минут с 22:00, так что 9-11 вечера

0 голосов
/ 18 января 2009

Я видел немало трюков для преобразования DATETIME в "просто время". Фактически, где я работаю, довольно много времени было потрачено на поиск самого быстрого. Кажется, что люди забывают, что «самый короткий код» не всегда самый быстрый и часто включает скрытые преобразования типов. Самое быстрое, что мы придумали, это ...

DATEADD (ДЕНЬ, DATEDIFF (МИНУТА, 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

Можно легко адаптировать это к нескольким ключевым временам дня, или диапазону времени, и т. Д., И т. Д. *


EDIT:

Как уже упоминалось в комментариях к этому ответу, изменение структуры базы данных также выиграет здесь. Наличие поля DATE, а также поля TIME. Часто лишнее, но в этом случае может быть полезным.

0 голосов
/ 18 января 2009

Не могли бы вы сделать это более эффективно, преобразовав дату и время в число unixtime и изменив его, чтобы указать время суток.

Предложение where отфильтровывает его по желаемому диапазону дат, а затем трюк мода отбрасывает все записи, которые были не в то время суток, которое вы хотели.

Тогда вы можете запросить его один раз, а не один раз за каждый день.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...