按月划分的SQL SERVER组日期时间戳

时间:2018-11-12 10:47:35

标签: sql sql-server datetime group-by

在过去3年中,我每15分钟就有一次intervaldata(值)。 datetimestamp的数据类型为datetimeoffset(7)。 每个时间间隔的datetimestamp必须解释为时间周期的结束。

例如,datetimestamp 2017-01-01 00:00:00.0000000 +01:00的值1.96是句点 从2016-12-31 23:45:00.0000000 +01:00到2017-01-01 00:00:00.0000000 +01:00

DateTime                            Value
2016-12-31 23:00:00.0000000 +01:00  2.0000000000
2016-12-31 23:15:00.0000000 +01:00  1.9600000000
2016-12-31 23:30:00.0000000 +01:00  2.0400000000
2016-12-31 23:45:00.0000000 +01:00  2.0000000000
2017-01-01 00:00:00.0000000 +01:00  1.9600000000
2017-01-01 00:15:00.0000000 +01:00  2.1200000000
2017-01-01 00:30:00.0000000 +01:00  2.0800000000
2017-01-01 00:45:00.0000000 +01:00  2.0000000000
2017-01-01 01:00:00.0000000 +01:00  2.0000000000

我想知道每月的总数。下面的查询给我错误的结果,因为datetimestamp 2017-01-01 00:00:00.0000000 +01:00被添加到2017年1月而不是2016年12月。

SELECT Year([datetimestamp])  AS [Year], 
       Month([datetimestamp]) AS [Month], 
       Sum([value])           AS [Total] 
FROM   [data] 
GROUP  BY Year([datetimestamp]), 
          Month([datetimestamp]) 
ORDER  BY [year], 
          [month]

2 个答案:

答案 0 :(得分:1)

因此,如果您减去一分钟,那么该组的年份和月份将正确吗?

SELECT 
 YEAR(Dt) AS [Year],
 MONTH(Dt) AS [Month],
 SUM([Value]) AS [Total]
FROM (
  SELECT
   DATEADD(MINUTE, -1, [datetimestamp]) AS Dt,
   [Value]
  FROM [data]
) q
GROUP BY YEAR(Dt), MONTH(Dt)
ORDER BY [Year], [Month];

或者不带子查询

SELECT 
 YEAR(DATEADD(MINUTE, -1, [datetimestamp])) AS [Year],
 MONTH(DATEADD(MINUTE, -1, [datetimestamp])) AS [Month],
 SUM([Value]) AS [Total]
FROM [data]
GROUP BY YEAR(DATEADD(MINUTE, -1, [datetimestamp])), 
         MONTH(DATEADD(MINUTE, -1, [datetimestamp]))
ORDER BY [Year], [Month];

答案 1 :(得分:1)

您可能会发现它更容易表达

SELECT YEAR(dts_start) AS [Year],
       MONTH(dts_start) AS [Month],
       SUM([Value]) AS [Total]
FROM data CROSS APPLY
     (VALUES (DATEADD(minute, -15, datetimestamp)) as v(dts_start)
GROUP BY YEAR(dts_start), MONTH(dts_start)
ORDER BY [Year], [Month];

您可能还会发现FORMAT()很方便:

SELECT FORMAT(dts_start, 'yyyy-MM') AS yyyymm,
       SUM([Value]) AS [Total]
FROM data CROSS APPLY
     (VALUES (DATEADD(minute, -15, datetimestamp)) as v(dts_start)
GROUP BY FORMAT(dts_start, 'yyyy-MM')
ORDER BY yyyymm;