SQL查询从累加器超过24小时返回15分钟总计

时间:2014-06-06 14:35:13

标签: sql sql-server

我有一些电表连接到PLC(可编程逻辑控制器) PLC在24小时内计算(积分)来自仪表的kWh脉冲 计数在午夜重置 每秒将当前计数值记录到表中。

我需要在每15分钟的时间内检索一米的电量。

例如:

Meter count at 11:00:00 = 1000  
Meter count at 11:14:59 = 1110  
Meter count at 11:29:59 = 1200       
Meter count at 11:59:59 = 1400

15分钟的总电量:

At 11:14:59 = 110  
At 11:29:59 = 90  
At 11:59:59 = 200  

基本上,我想从前15分钟的计数中减去15分钟的计数。

数据库是MSSQLServer 是否可以使用选择查询返回上述内容 我需要将此数据导出到csv文件。

3 个答案:

答案 0 :(得分:2)

我认为CTE和自我联接足以实现预期的结果:

--constructing ID
WITH vPLC as (select *, ROW_NUMBER() OVER (order by date) as recID  
from @PLC
)
select vPLC.*, COALESCE( vPLC.value - n.Value, 0 ) as diffVal
from vPLC
     left JOIN vPLC n on n.recID = vPLC.recID - 1

----------OUTPUT----------
recId  date                 value   diffVal
1      6/5/2014 11:00:00 AM 1000    0
2      6/5/2014 11:14:59 AM 1110    110
3      6/5/2014 11:29:59 AM 1200    90
4      6/5/2014 11:59:59 AM 1400    200

Proof code is here

答案 1 :(得分:1)

以下查询将获取四分之一小时的数据,而不是在OP数据之前的一秒钟。

OP没有提供表模式,这个答案使用了这个

CREATE TABLE UtilityMeter (
  _Time Time
, KWh Int
)

服务器应该是SQLServer 2008或更高版本(使用TIME类型)

要做的第一件事就是过滤数据以仅获得季度

SELECT _Time, KWh
FROM   UtilityMeter
WHERE  _Time = Cast(DateAdd(mi, DateDiff(mi, 0, _Time) / 15 * 15, 0) as Time)

DateDiff返回一个整数,因此minutes / 15是一个整数除法,minutes / 15 * 15不会返回分钟,而是返回它之前的四分之一。

现在,如果SQLServer更好2012,则可以使用LAG

With Quarter AS (
  SELECT _Time, KWh
  FROM   UtilityMeter
  WHERE  _Time = Cast(DateAdd(mi, DateDiff(mi, 0, _Time) / 15 * 15, 0) as Time)
)
SELECT _Time
     , BlockConsume = KWh - LAG(KWh, 1, 0) OVER (ORDER BY _Time)
FROM   Quarter;

否则需要自动<{1}}

JOIN

With Quarter AS ( SELECT _Time, KWh , ID = Row_Number() OVER (ORDER BY _Time) FROM UtilityMeter WHERE _Time = Cast(DateAdd(mi, DateDiff(mi, 0, _Time) / 15 * 15, 0) as Time) ) SELECT _1._Time , BlockConsume = _1.KWh - _2.KWh FROM Quarter _1 INNER JOIN Quarter _2 ON _1.ID = _2.ID + 1 中添加的计算ID是为了简化CTE条件。

带有查询和生成数据的

SQLFiddle demo

答案 2 :(得分:0)

我将此作为单独的答案发布,因为它使用了不同的方法解决问题,如果这不是正确的事情,我将编辑我之前的答案以添加此答案。


要获得问题中的结果,可以利用数据的固有属性:消耗的kW不会减少,这意味着最小值将始终是第一个,最大值将始终是最后一个每个街区。

快速&amp;使用这些属性的脏查询是

SELECT MAX(_Time) _Time
     , BlockConsume = MAX(KWh) - MIN(KWh)
FROM   UtilityMeter
GROUP BY DateDiff(mi, 0, _Time) / 15
ORDER BY _Time

小组锚点在确切的四分之一小时内发生变化,MAX(_Time)将是精确四分之一之前的最后一个值:14.59,29.59,44.59,59.99。

查询有效,但它是一个表扫描,为了更快一点,可以通过过滤掉不是最后一个组的所有898 (15*60-2)行来删除所有未使用的数据< / p>

WITH Quarter AS (
  SELECT _Time, KWh
       , DateDiff(mi, 0, _Time) / 15 Block
  FROM   UtilityMeter
  WHERE  DateDiff(s, 0, _Time) % (900) IN (0, 899)
)
SELECT MAX(_Time) _Time
     , BlockConsume = MAX(KWh) - MIN(KWh)
FROM   Quarter
GROUP BY Block
ORDER BY _Time