每个月申请一个减法

时间:2017-07-24 14:38:47

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

我有一个捕获数据的Wonderware Historian服务器。我必须用SQL查询它以找出一个月的最后一个值和一个月的第一个值之间的差异(该值不断增长)。

要选择我的数据,我这样做了:

SELECT Annees=YEAR(DateTime),Mois=MONTH(DateTime),Value=()
FROM AnalogHistory where TagName = 'OBJECT_TAG_NAME'
AND DateTime >= '01/01/2016 00:00:00' 
AND DateTime <= '24/07/2017 13:53:31';

我想我需要使用grouporder by,但就目前而言,我仍然坚持如何获得一个月的最后一个值和第一个值来减去它。 / p>

您知道应用查询的方法吗?

修改

实际上,我想通过创建一个包含“每月消耗量”(天然气,电力,水......)的图表来执行统计数据。该指数在不断增长,因此每个月我都需要从最后一个值中减去第一个值。

例如,假设我有这种数据:

Date                | Index
------              | ------
2017-05-01 00:00:00 | 12
2017-05-01 03:57:00 | 14
2017-05-29 15:00:00 | 97
2017-05-31 22:54:00 | 104
2017-06-01 03:54:00 | 107
2017-06-30 21:54:00 | 211

2017年5月的结果必须是104-12 ==&gt; 92 2017年6月的结果必须是211-104 ==&gt; 107

然后,这将显示在条形图中。

4 个答案:

答案 0 :(得分:4)

使用 FIRST_VALUE 窗口功能

;with cte as
(
SELECT distinct 
   Annees=YEAR(DateTime),
   Mois=MONTH(DateTime),
   firstRecord = first_value(value)over(partition by YEAR(DateTime),MONTH(DateTime) order by DateTime asc),
   lastRecord = first_value(value)over(partition by YEAR(DateTime),MONTH(DateTime) order by DateTime desc)
FROM AnalogHistory 
where TagName = 'OBJECT_TAG_NAME'
AND DateTime >= '01/01/2016 00:00:00' 
AND DateTime <= '24/07/2017 13:53:31'
)
select 
    Annees,
    Mois, 
    value = isnull(lastRecord,0) - isnull(firstRecord ,0)
from cte
旧版本的

Row_Number方法

;with cte as
(
SELECT 
   Annees=YEAR(DateTime),
   Mois=MONTH(DateTime),
   firstRecord = Row_Number(value)over(partition by YEAR(DateTime),MONTH(DateTime) order by DateTime asc),
   lastRecord = Row_Number(value)over(partition by YEAR(DateTime),MONTH(DateTime) order by DateTime desc)
FROM AnalogHistory 
where TagName = 'OBJECT_TAG_NAME'
AND DateTime >= '01/01/2016 00:00:00' 
AND DateTime <= '24/07/2017 13:53:31'
)
select Annees,Mois,
       min(case when lastRecord = 1 then value end) - 
       min(case when firstRecord = 1 then value end)
From Cte 
Where 1 in (lastRecord,firstRecord )
Group by Annees,Mois

答案 1 :(得分:1)

如果值越来越大,那么使用每个月的最小值和最大值而不是第一个和最后一个(它们应该是同一个)更容易。

SELECT 
    YEAR(DateTime) AS Annee, MONTH(DateTime) AS Mois,
    MIN(Value) As MinVal, MAX(Value) As MaxVal,
    MAX(Value) - MIN(Value) As Difference,
FROM AnalogHistory 
WHERE
    TagName = 'OBJECT_TAG_NAME' AND
    DateTime >= '01/01/2016 00:00:00' AND
    DateTime <= '24/07/2017 13:53:31'
GROUP BY YEAR(DateTime), MONTH(DateTime)
ORDER BY YEAR(DateTime), MONTH(DateTime)

答案 2 :(得分:0)

这将从您的表中选择DateTime字段在当前月份内的值。这是你想要的吗?

SELECT Value, *
FROM AnalogHistory 
WHERE TagName = 'OBJECT_TAG_NAME'
AND YEAR(DatTime) = YEAR(GETDATE())
AND MONTH(DateTime) = MONTH(GETDATE())

答案 3 :(得分:0)

您可以使用像这样的SQL

 WITH cte_min_date 
     AS (SELECT Row_number() 
                  OVER ( 
                    partition BY Year([datetime]) * 100 + Month([datetime]) 
                    ORDER BY [datetime]) AS rn, 
                [datetime], 
                [value] 
         FROM   analoghistory 
         WHERE  tagname = 'OBJECT_TAG_NAME' 
                AND datetime >= '01/01/2016 00:00:00' 
                AND datetime <= '24/07/2017 13:53:31'), 
     cte_max_date 
     AS (SELECT Row_number() 
                  OVER ( 
                    partition BY Year([datetime]) * 100 + Month([datetime]) 
                    ORDER BY [datetime] DESC) AS rn, 
                [datetime], 
                [value] 
         FROM   analoghistory 
         WHERE  tagname = 'OBJECT_TAG_NAME' 
                AND datetime >= '01/01/2016 00:00:00' 
                AND datetime <= '24/07/2017 13:53:31') 
SELECT a.[datetime], 
       b.[datetime], 
       Year(a.[datetime]) * 100 + Month(a.[datetime]), 
       b.[value] - a.[value] AS [Value] 
FROM   cte_min_date a 
       INNER JOIN cte_max_date b 
               ON Year(a.[datetime]) * 100 + Month(a.[datetime]) = 
                             Year(b.[datetime]) * 100 + Month(b.[datetime]) 
                  AND a.rn = b.rn 
WHERE  a.rn = 1