2017-04-22 28 views
3

問題:

嗨,我有與歷史數據的表從一堆傳感器,而我試圖讓一排各個歷史數據在時間上最接近所需的時間。例如,我想獲得最接近每分鐘的記錄。獲取行時最接近的時間爲每行中的另一個表

我簡化了問題;下面,如果我能解決我可以用它來通知我的一般解決方案:

以兩個表如下:

CREATE TABLE [TempDataTable](
[DataIndex] [int] IDENTITY(0,2) NOT NULL, 
[DataName] [varchar](40) NOT NULL, 
[DataValue] [decimal](10,2) NOT NULL, 
[DataTimeStamp] [datetime2](7) 
) 

CREATE TABLE [TempTargetTable](
[TargetIndex] [int] IDENTITY(1,2) NOT NULL, 
[TargetTime] [datetime2](7) 
) 

對於每一行TempTargetTable,得到TempDataTable行與TempDataTable.DataTimeStamp最接近TempTargetTable.TargetTime

如果我能做到這一點,我相信我可以找出休息,但是我對如何讓這第一步工作感到茫然。爲了便於測試你的代碼,我可以提供一些測試數據填充兩個表如下:

有用的測試數據:

INSERT INTO [TempDataTable] 
    ([DataName], 
    [DataValue], 
    [DataTimeStamp]) 
VALUES 
    ('Sensor',0, '2017-01-01 00:00:00'), 
    ('Sensor',0.5, '2017-01-01 00:00:17'), 
    ('Sensor',1, '2017-01-01 00:01:03'), 
    ('Sensor',1.5, '2017-01-01 00:01:30'), 
    ('Sensor',1.5, '2017-01-01 00:01:38'), 
    ('Sensor',2, '2017-01-01 00:02:01'), 
    ('Sensor',2.5, '2017-01-01 00:02:15'), 
    ('Sensor',3, '2017-01-01 00:02:56'), 
    ('Sensor',3.5, '2017-01-01 00:03:27'), 
    ('Sensor',4, '2017-01-01 00:04:01'), 
    ('Sensor',5, '2017-01-01 00:05:00'), 
    ('Sensor',5.5, '2017-01-01 00:05:15'), 
    ('Sensor',5.5, '2017-01-01 00:05:46'), 
    ('Sensor',6, '2017-01-01 00:06:10'), 
    ('Sensor',7, '2017-01-01 00:06:57'), 
    ('Sensor',7.5, '2017-01-01 00:07:13'), 
    ('Sensor',8, '2017-01-01 00:08:01'), 
    ('Sensor',9, '2017-01-01 00:09:03') 

INSERT INTO [TempTargetTable] 
    ([TargetTime]) 
VALUES 
    ('2017-01-01 00:00:00'), 
    ('2017-01-01 00:01:00'), 
    ('2017-01-01 00:02:00'), 
    ('2017-01-01 00:03:00'), 
    ('2017-01-01 00:04:00'), 
    ('2017-01-01 00:05:00'), 
    ('2017-01-01 00:06:00'), 
    ('2017-01-01 00:07:00'), 
    ('2017-01-01 00:08:00'), 
    ('2017-01-01 00:09:00') 
+0

我將創建此自定義函數,如getSensorByTime(時間)在這個函數中,計算值的時間之間的diff文件,命令的diff ASC和限制1. – ARS81

回答

1

爲您發佈(簡化的)當前的問題我做了以下內容:

交叉連接的表,使每個目標時間的差異,每個現有數據時間戳。 然後應用DENSE_RANK函數,該函數將爲每個TargetTime提供排名,然後僅選擇具有毫秒差異的記錄。

你可以找到一個工作解決方案here

select TargetIndex, TargetTime, DataIndex, DataName, DataValue, DataTimeStamp 
from 
    (
    select t.*, DENSE_RANK() OVER(PARTITION BY t.targetindex ORDER BY t.diff) as Rank 
    from 
    (
     select tg.targetindex, tg.targettime, t.dataindex, t.dataname, t.datavalue, t.datatimestamp, abs(datediff(ms, tg.TargetTime, t.DataTimeStamp)) diff 
     from TempDataTable t cross join TempTargetTable tg 
    ) t 
) f 
where Rank = 1 
+0

非常感謝你,這工作完美!爲了防止溢出,我不得不使用bigint版本,所以對於未來的人來說,嘗試遵循這一點可能是必要的。 – ObviouslyFake

0

如果你想在每個日曆分鐘的第一個記錄,你可以使用row_number()

select tdt.* 
from (select tdt.*, 
      row_number() over (partition by format(DataTimeStamp, 'yyyy-MM-dd HH:mm') 
           order by DataTimeStamp asc 
           ) as seqnum 
     from TempDataTable tdt 
    ) tdt 
where seqnum = 1; 
+0

戈登,錯過「YYYY-後一個右括號MM-dd HH:mm'。 – Jason

+0

@Jason。 。 。謝謝。 –

0

如果我在讀你的問題正確的您想要的最接近的記錄,即使它是前一分鐘。如果是這樣,你可以查詢這個問題。我這樣做是在多個步驟,讓你可以輕鬆地跟蹤(我希望)

我做了什麼:

  • 找到最接近的分,如果秒> = 30輪至下一分鐘還保持實際分鐘
  • 計算秒的差異,發現它的ABS值
  • 得到最接近的值的時間點

查詢

SELECT tempd.TargetTime, tdfinal.DataName, tdfinal.DataValue, tdfinal.DataTimeStamp 
FROM @TempTargetTable as tempd 
LEFT OUTER JOIN 
    (SELECT tdseconds.*, ROW_NUMBER() OVER(PARTITION BY closestMinute ORDER BY secondDiff) AS r 
    FROM (SELECT td.*, ABS(DATEDIFF(SECOND, DataTimeStamp, closestMinute)) AS secondDiff 
      FROM (SELECT DataName,DataValue,DataTimeStamp, 
        CONVERT(DATETIME,CONVERT(DATE, datatimestamp, 121)) + 
        CONVERT (DATETIME,TIMEFROMPARTS(DATEPART(HOUR, datatimestamp), 
          CASE WHEN DATEPART(SECOND, DataTimeStamp) >= 30 
            THEN DATEPART(MINUTE, DATATimeStamp) + 1 
            ELSE DATEPART(MINUTE, DATATimeStamp) END, 0,0,0), 121) AS closestMinute 
       FROM @TempDataTable) AS td 
     ) AS tdseconds 
    ) AS tdfinal 
ON tdfinal.closestMinute = tempd.TargetTime 
WHERE tdfinal.r = 1 

結果

TargetTime    DataName DataValue DataTimeStamp 
2017-01-01 00:00:00.000 Sensor 0.00  2017-01-01 00:00:00.000 
2017-01-01 00:01:00.000 Sensor 1.00  2017-01-01 00:01:03.000 
2017-01-01 00:02:00.000 Sensor 2.00  2017-01-01 00:02:01.000 
2017-01-01 00:03:00.000 Sensor 3.00  2017-01-01 00:02:56.000 
2017-01-01 00:04:00.000 Sensor 4.00  2017-01-01 00:04:01.000 
2017-01-01 00:05:00.000 Sensor 5.00  2017-01-01 00:05:00.000 
2017-01-01 00:06:00.000 Sensor 6.00  2017-01-01 00:06:10.000 
2017-01-01 00:07:00.000 Sensor 7.00  2017-01-01 00:06:57.000 
2017-01-01 00:08:00.000 Sensor 8.00  2017-01-01 00:08:01.000 
2017-01-01 00:09:00.000 Sensor 9.00  2017-01-01 00:09:03.000 
相關問題