[英]Combining multiple SQL queries of a single table into separate columns
遇到一个艰难的时期,只是想出一个标题来解释我想做的事情。.我已经搜索了一段时间,但一无所获。
使用SQL Server 2008r2 Enterprise
我正在尝试针对单个表获取多个结果(列)。 该表如下所示:
sample_id sampletime samplevalue
100 2013-09-07 00:00:00.000 12
101 2013-09-07 00:00:00.000 15
102 2013-09-07 00:00:00.000 11
100 2013-09-07 00:05:00.000 14
101 2013-09-07 00:05:00.000 12
102 2013-09-07 00:05:00.000 13
我想做的是获取每天/每周/等的每个sample_id的平均值,但将每个sample_id设为一列。 我目前有这个查询:
select
DATEDIFF(ww, GETDATE(), sampletime) AS weeks_ago,
AVG(samplevalue) AS item1
from table
where
sample_id = '100'
and sampletime between '2013-09-01' AND '2013-10-01'
group by DATEDIFF(ww,getdate(),sampletime)
order by weeks_ago
这给了我以下输出:
weeks_ago item1
-5 10.717936
-4 13.009690
-3 11.401884
-2 11.073626
-1 15.417648
0 18.399488
这正是我希望输出看起来的样子,但是问题是我需要对数十种不同的sample_id进行此查询,并且我真的很想使输出看起来像这样:
weeks_ago item1 item2 item3
-5 10.717936 11.401884 6.944170
-4 13.009690 10.717936 8.330120
-3 11.401884 18.399488 7.476393
-2 11.073626 15.417648 7.933386
-1 15.417648 13.009690 9.651132
0 18.399488 18.399488 7.456417
依此类推...我尝试使用'IN'并包含一堆sample_id,如下所示:
select
sample_id,
DATEDIFF(ww, GETDATE(), sampletime) AS weeks_ago,
AVG(samplevalue) AS avg_vol
from table
where
sample_id in ('100','101','102')
and sampletime between '2013-09-01' AND '2013-10-01'
group by DATEDIFF(ww,getdate(),sampletime), sample_id
order by weeks_ago
但这给了我这样的输出:
sample_id avg_vol weeks_ago
100 6.834470 -4
101 3.235943 -4
102 3.952023 -4
100 10.330120 -3
101 4.753588 -3
102 3.928382 -3
100 1.401884 -2
101 7.476393 -2
102 6.426609 -2
这不是很好,因为它无法弄清特定项目的平均体积是如何随时间变化的。.不确定我是否在解释问题所在方面做得很好,但是如果有人有任何建议,我会非常非常感谢!
解决了!
SELECT weeks_ago, [100] as item1, [101] as item2, [102] as item3, [n..]
FROM (
SELECT
sample_id,
DATEDIFF(ww, GETDATE(), sampletime) as weeks_ago,
samplevalue
FROM table
WHERE sample_id in (100,101,102,n...)
AND sampletime between 'YYYY-MM-DD' and 'YYYY-MM-DD'
) main
PIVOT (
AVG(samplevalue) for sample_id in ([100],[101],[102],[n..])
) pvt
谢谢你们每一个人的帮助!
正如肖恩·兰格(Sean Lange)在上面的评论中提到的那样,听起来您想对Pivot
进行数据Pivot
,以便可以获取每个项目。
使用上述设置的示例:
select weeks_ago, pvt.[100], pvt.[101], pvt.[102]
FROM (
select
sample_id,
DATEDIFF(ww, GETDATE(), sampletime) AS weeks_ago,
samplevalue
from #sample
) main
PIVOT
(
AVG(samplevalue) FOR sample_id in ([100], [101], [102])
) pvt
Pivot的缺点是,除非您动态生成此查询,否则您必须提前知道所有样本,这可能会很乏味。
动态生成的示例:
DECLARE @string nvarchar(max) = '', @sql nvarchar(max) = '';
select @string =
(
select distinct '[' + cast(sample_id as varchar(5)) + '],' from #sample FOR XML PATH('')
)
select @string = LEFT(@string, LEN(@string)-1)
select @string
SELECT @sql =
'
select weeks_ago, '+@string+'
FROM (
select
sample_id,
DATEDIFF(ww, GETDATE(), sampletime) AS weeks_ago,
samplevalue
from #sample
) main
PIVOT
(
AVG(samplevalue) FOR sample_id in ('+@string+')
) pvt
'
EXEC (@sql);
但是,使用动态SQL可能会很棘手,如果您不习惯使用动态SQL,或者由于SQL的危险而直接调用代码(而不是说存储过程),则不建议使用动态SQL。注射之类的。
我对SQL Server不太熟悉,但是在四处搜寻之后,我发现了一个可行的解决方案。
首先,为了简化一切,创建一个临时表:
select
sample_id,
DATEDIFF(ww, GETDATE(), sampletime) AS weeks_ago,
AVG(samplevalue) AS avg_vol
into #temp_table
from table
where
sample_id in ('100','101','102')
and sampletime between '2013-09-01' AND '2013-10-01'
group by DATEDIFF(ww,getdate(),sampletime), sample_id
order by weeks_ago;
现在使用#temp_table
。 首先,让我们获得唯一的“ sample_id”值:
DECLARE @DynamicPivotQuery AS NVARCHAR(MAX);
DECLARE @ColumnName AS NVARCHAR(MAX);
SELECT @ColumnName= ISNULL(@ColumnName + ',','')
+ QUOTENAME(sample_id)
FROM (SELECT DISTINCT sample_id FROM #temp_table) AS t;
现在,让我们构建数据透视表:
--Prepare the PIVOT query using the dynamic
SET @DynamicPivotQuery =
N'SELECT week_ago, ' + @ColumnName + '
FROM #temp_table
PIVOT(SUM(avg_vol)
FOR week_ago IN (' + @ColumnName + ')) AS PVTTable'
--Execute the Dynamic Pivot Query
EXEC sp_executesql @DynamicPivotQuery;
希望这可以帮助。
参考:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.