我有一些电表连接到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文件。
答案 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
答案 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
条件。
答案 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