带有GROUP BY的SQL Server 2014时间戳和PIVOT

时间:2016-11-06 21:18:24

标签: sql sql-server tsql sql-server-2014

这可能很容易,但我无法得到它所以我想我会问。

我正在使用SQL Server 2014,并且有一个包含以下列的表:

id, int
date, datetime
sensorId, varchar(45)
observedObjId, varchar(45)

我想查询一下我提供以下输入:

sensorId_1
sensorId_2
startDateTime
endDateTime
intervalAmount
intervalTime

然后输出将是一个结果集,其中两个传感器ID作为列,每行将是startDateTime和endDateTime之间的时间间隔 - 例如,5分钟,1小时,1天等等。然后交叉点的值将是特定传感器的observeObjIds数量的计数。

我从未接触到它的PIVOT部分因为我无法使GROUP BY部分正确。我正在忙于DATEPART(datepart, date)的分组,但这似乎失去了剩下的日期的背景,所以没有很好地完成。

有什么建议吗?

2 个答案:

答案 0 :(得分:0)

我会像GROUP BY这样对基于DAY的分组进行分组(在动态SQL中,以实现基于指定传感器的动态列命名):

DECLARE @sensorId_1 INT, 
        @sensorId_2 INT,
        @startDateTime DATETIME,
        @endDateTime DATETIME

-- For example, return data for Sensors 3 and 7 within the month of Feb 2016
SET @sensorId_1 = 3
SET @sensorId_2 = 7
SET @startDateTime = '2016-02-01'
SET @endDateTime = '2016-03-01'

DECLARE @sql NVARCHAR(MAX)

SET @sql =
'SELECT CAST([date] AS DATE) AS [Day], 
        SUM(CASE WHEN sensorId = ' + CONVERT(VARCHAR,@sensorId_1) + ' THEN 1 ELSE 0 END) AS Sensor_' + CONVERT(VARCHAR,@sensorId_1) + ',' +
      ' SUM(CASE WHEN sensorId = ' + CONVERT(VARCHAR,@sensorId_2) + ' THEN 1 ELSE 0 END) AS Sensor_' + CONVERT(VARCHAR,@sensorId_2) +
' FROM [SensorData] 
  WHERE sensorId IN (' + CONVERT(VARCHAR,@sensorId_1) + ', ' + CONVERT(VARCHAR,@sensorId_2) + ') ' +
' AND [date] >= ' + QUOTENAME(CONVERT(VARCHAR,@startDateTime,120),'''') +
' AND [date] < ' + QUOTENAME(CONVERT(VARCHAR,@endDateTime,120),'''') +
' GROUP BY CAST([date] AS DATE)
  ORDER BY CAST([date] AS DATE)'

EXEC sp_executesql @sql

对于每小时的细分,我只想改变@sql定义:

SET @sql =
'SELECT CONVERT(VARCHAR,CAST([date] AS DATE)) + '' '' + CONVERT(VARCHAR,DATEPART(HOUR,[date])) + '':00'' AS [Hour], 
        SUM(CASE WHEN sensorId = ' + CONVERT(VARCHAR,@sensorId_1) + ' THEN 1 ELSE 0 END) AS Sensor_' + CONVERT(VARCHAR,@sensorId_1) + ',' +
      ' SUM(CASE WHEN sensorId = ' + CONVERT(VARCHAR,@sensorId_2) + ' THEN 1 ELSE 0 END) AS Sensor_' + CONVERT(VARCHAR,@sensorId_2) +
' FROM [SensorData] 
  WHERE sensorId IN (' + CONVERT(VARCHAR,@sensorId_1) + ', ' + CONVERT(VARCHAR,@sensorId_2) + ') ' +
' AND [date] >= ' + QUOTENAME(CONVERT(VARCHAR,@startDateTime,120),'''') +
' AND [date] < ' + QUOTENAME(CONVERT(VARCHAR,@endDateTime,120),'''') +
' GROUP BY CONVERT(VARCHAR,CAST([date] AS DATE)) + '' '' + CONVERT(VARCHAR,DATEPART(HOUR,[date])) + '':00''
  ORDER BY CONVERT(VARCHAR,CAST([date] AS DATE)) + '' '' + CONVERT(VARCHAR,DATEPART(HOUR,[date])) + '':00'''

如果您希望能够动态指定间隔(分钟,日,月等)以及您希望在每个“桶”中包含的间隔的单位数,那么您需要将其设为有点复杂。

我会有一个CASE语句,根据您可能想要处理的不同时间间隔(可能是相当有限的?)来确定动态SQL的构建方式,但我不熟悉{{1} ,或许这可能会给你一个更优雅的解决方案。

希望这对PIVOT部分有帮助,对不起,如果我完全错过了这一点,你已经理解了这一点!

答案 1 :(得分:0)

您希望它转移到doReturn(Future.successful(Seq("hello"))).when(client).findR‌​esult("1234"),但按sensorID分组?

对于intervalAmount * datediff(intervalTime, startDateTime, endDateTime),请尝试:

group by