2016-11-06 38 views
0

这可能很容易,但我一直无法得到它,所以我想我会问。带有GROUP BY的SQL Server 2014时间戳和PIVOT

我使用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天等,然后分别显示十字路口将是pObjectsId的数量的计数关节传感器。

我从来没有得到过它的PIVOT片断,因为我无法获得正确的GROUP BY部分。我被DATEPART(datepart, date)搞乱了,但是这似乎失去了日期的其他部分,所以没有很好地完成。

有什么建议吗?

回答

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是如何建立的(取决于可能需要处理的不同时间间隔(可能相当有限?)),但我不熟悉PIVOT,所以也许可以给出你更优雅的解决方案。

无论如何,希望可以帮助GROUP BY部分,对不起,如果我完全错过了这一点,并且您已经理解了它的这个元素!

0

你想要它翻转sensorID,但按intervalAmount * datediff(intervalTime, startDateTime, endDateTime)分组?

group by,请尝试:

select 
    sensorID, 
    @intervalAmount * datediff(@intervalTime, @startDateTime, @endDateTime) as timeSpanGroup, 
    count(*) 
from 
    tbl 
where 
    date >= @startDateTime and 
    date <= @endDateTime and 
    sensorId in (@sensorID_1, @sensorID_2) 
group by 
    sensorID, @intervalAmount * datediff(@intervalTime, @startDateTime, @endDateTime)