SQL Server之间的差异很多不规则的测量值

时间:2016-01-04 11:19:57

标签: sql sql-server tsql sql-server-2012

我有一个SQL服务器数据库,其中包含一个包含100个测量点的测量数据的表。以大约5秒的间隔测量每一个。它具有以下格式:

MeasurementPointID           timestamp              value
001234                       03-01-2015 00:02:03    100
001234                       03-01-2015 00:02:08    120
001234                       03-01-2015 00:02:13    130
001234                       03-01-2015 00:02:19    160
001234                       03-01-2015 00:02:22    200
001236                       03-01-2015 00:02:04    400
001236                       03-01-2015 00:02:09    405
001236                       03-01-2015 00:02:14    420
001236                       03-01-2015 00:02:19    445
001236                       03-01-2015 00:02:25    470
Etc.

我想知道如何根据以前的时间戳除以时间段(自前时间戳)以来测量值的变化来制作视图

MeasurementPointID           timestamp              changeDivPeriod
001234                       03-01-2015 00:02:03    0 <-- Zero would be nice here
001234                       03-01-2015 00:02:08    4
001234                       03-01-2015 00:02:13    2
001234                       03-01-2015 00:02:19    5
001234                       03-01-2015 00:02:22    13,333333
001236                       03-01-2015 00:02:04    0 <-- Zero would be nice here
001236                       03-01-2015 00:02:09    1
001236                       03-01-2015 00:02:14    3
001236                       03-01-2015 00:02:19    5
001236                       03-01-2015 00:02:25    4,166666
Etc.

我将如何做到这一点?首先用一种观点解决这个问题是否明智?

我认为将触发器添加到此表并使用计算值填充新表(而不是视图)会更快/更容易。如果是这样,我该怎么做?

1 个答案:

答案 0 :(得分:3)

你可以使用窗口函数和自连接(如果需要用视图包装它):

WITH cte AS
(
  SELECT *,
    rn = ROW_NUMBER() OVER (PARTITION BY MeasurementPointID ORDER BY [timestamp])
  FROM #tab
)
SELECT c1.MeasurementPointID,
       c1.[timestamp],
       [changeDivPeriod] = 
           CASE WHEN c1.rn = 1 THEN 0 
                ELSE 1.0 * (c1.[value] - c2.[value]) 
                     / NULLIF(DATEDIFF(second, c2.[timestamp], c1.[timestamp]),0)
           END
FROM cte c1
LEFT JOIN cte c2
  ON c1.MeasurementPointID = c2.MeasurementPointID 
  AND c1.rn = c2.rn+1;

LiveDemo

输出:

╔════════════════════╦═════════════════════╦═════════════════╗
║ MeasurementPointID ║      timestamp      ║ changeDivPeriod ║
╠════════════════════╬═════════════════════╬═════════════════╣
║             001234 ║ 2015-03-01 00:02:03 ║ 0               ║
║             001234 ║ 2015-03-01 00:02:08 ║ 4               ║
║             001234 ║ 2015-03-01 00:02:13 ║ 2               ║
║             001234 ║ 2015-03-01 00:02:19 ║ 5               ║
║             001234 ║ 2015-03-01 00:02:22 ║ 13.333333333333 ║
║             001236 ║ 2015-03-01 00:02:04 ║ 0               ║
║             001236 ║ 2015-03-01 00:02:09 ║ 1               ║
║             001236 ║ 2015-03-01 00:02:14 ║ 3               ║
║             001236 ║ 2015-03-01 00:02:19 ║ 5               ║
║             001236 ║ 2015-03-01 00:02:25 ║ 4.166666666666  ║
╚════════════════════╩═════════════════════╩═════════════════╝

使用SQL Server 2012+,您可以使用 LEAD/LAG

SELECT 
  MeasurementPointID,
  [timestamp],
  [changeDivPeriod] =  COALESCE(1.0 * ([value] - LAG ([value]) OVER ( PARTITION BY MeasurementPointID ORDER BY [timestamp] )) 
                               / NULLIF(DATEDIFF(second, LAG ([timestamp]) OVER ( PARTITION BY MeasurementPointID ORDER BY [timestamp]), [timestamp]),0),0)
FROM #tab

LiveDemo2