我目前使用Linq-2-Sql来执行相当复杂的查询。但效率非常低,导致服务器多次往返。
使用一些连接我设法将数据转换为这样的格式:
Sensor -- Timestamp -- Value
A -- 12/02/2013 09:00 -- 10.4
A -- 12/02/2013 10:00 -- 10.3
A -- 12/02/2013 11:00 -- 10.1
B -- 12/02/2013 09:00 -- 15.3
B -- 12/02/2013 10:00 -- 16.4
B -- 12/02/2013 11:00 -- 15.4
我希望在像
这样的输出中使用它TimeStamp -- SensorA -- SensorB
12/02/2013 09:00 -- 10.4 -- 15.3
12/02/2013 10:00 -- 10.3 -- 16.4
12/02/2013 11:00 -- 10.1 -- 15.4
我猜我需要动态支点?任何人都可以帮助我指出正确的方向吗?
编辑 - 显然有超过2个传感器...理想情况下我需要这个能够按列扩展。我甚至不知道SQL Server是否可以这样做,所以任何帮助都表示赞赏。
答案 0 :(得分:2)
您需要使用PIVOT
函数来转换数据。
如果您的Sensor
值有限,则可以对查询进行硬编码:
select *
from
(
select sensor, timestamp, value
from yourtable
) src
pivot
(
max(value)
for sensor in (A, B)
) piv
但是如果值未知,那么您将需要实现动态SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Sensor)
from yourtable -- table containing Sensor values
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT timestamp, ' + @cols + ' from
(
select sensor, timestamp, value
from yourtable
) x
pivot
(
max(value)
for sensor in (' + @cols + ')
) p '
execute(@query)
两者都会给出结果:
| TIMESTAMP | A | B |
-------------------------------------
| 2013-12-02 09:00:00 | 10.4 | 15.3 |
| 2013-12-02 10:00:00 | 10.3 | 16.4 |
| 2013-12-02 11:00:00 | 10.1 | 15.4 |
注意,您将用当前查询替换yourtable
。
编辑#1,如果要按日期过滤,可以使用以下动态sql:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX),
@startdate datetime,
@enddate datetime
set @startdate = '2013-12-01'
set @enddate = '2013-12-03'
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Sensor)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT timestamp, ' + @cols + ' from
(
select sensor, timestamp, value
from yourtable
where timestamp >= '''+convert(varchar(10), @startdate, 120)+'''
and timestamp <= '''+convert(varchar(10), @enddate, 120)+'''
) x
pivot
(
max(value)
for sensor in (' + @cols + ')
) p '
execute(@query)