简体   繁体   English

将单个表的多个SQL查询合并到单独的列中

[英]Combining multiple SQL queries of a single table into separate columns

Had a tough time just coming up with a title that explains what I'm trying to do.. I've been googling for a while and am not getting anywhere. 遇到一个艰难的时期,只是想出一个标题来解释我想做的事情。.我已经搜索了一段时间,但一无所获。

Using SQL Server 2008r2 Enterprise 使用SQL Server 2008r2 Enterprise

I'm trying to get multiple results (columns) for queries against a single table. 我正在尝试针对单个表获取多个结果(列)。 The table looks something like this: 该表如下所示:

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

What I'd like to do is get a averages per sample_id per day/week/etc but have each sample_id be a column. 我想做的是获取每天/每周/等的每个sample_id的平均值,但将每个sample_id设为一列。 I currently have this query: 我目前有这个查询:

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

That gives me the following output: 这给了我以下输出:

weeks_ago  item1
-5         10.717936
-4         13.009690
-3         11.401884
-2         11.073626
-1         15.417648
0          18.399488

That's exactly how I want the output to look, however the issue is that I need to do this query for dozens of different sample_id's, and I'd really like to get the output to look something like this: 这正是我希望输出看起来的样子,但是问题是我需要对数十种不同的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

And so on... I've tried using 'IN' and including a bunch of sample_id's like so: 依此类推...我尝试使用'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

But that gives me output like this: 但这给了我这样的输出:

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

That's not great because it doesn't make it clear how the avg volume has changed for specific items over time.. Not sure if I'm doing a good job of explaining what the problem is but if anyone has any suggestions I'd very much appreciate it! 这不是很好,因为它无法弄清特定项目的平均体积是如何随时间变化的。.不确定我是否在解释问题所在方面做得很好,但是如果有人有任何建议,我会非常非常感谢!

Solved! 解决了!

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

Thank you everyone for your help! 谢谢你们每一个人的帮助!

As Sean Lange mentions in a comment above, it sounds like you want to do a Pivot on your data so that you can get each item. 正如肖恩·兰格(Sean Lange)在上面的评论中提到的那样,听起来您想对Pivot进行数据Pivot ,以便可以获取每个项目。

An example using your set above: 使用上述设置的示例:

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 

The disadvantage to Pivot is that, unless you generate this query dynamically, you have to know all of your samples ahead of time, which could get tedious. Pivot的缺点是,除非您动态生成此查询,否则您必须提前知道所有样本,这可能会很乏味。

Example of dynamic generation: 动态生成的示例:

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);

Using dynamic SQL can be tricky, though, and I don't recommend using it if you're not used to using it, or if you're calling code directly (rather than say, a stored procedure) because of the dangers of SQL injection and the like. 但是,使用动态SQL可能会很棘手,如果您不习惯使用动态SQL,或者由于SQL的危险而直接调用代码(而不是说存储过程),则不建议使用动态SQL。注射之类的。

I'm not quite familiar with SQL server, but after googling around, I found a solution that might work. 我对SQL Server不太熟悉,但是在四处搜寻之后,我发现了一个可行的解决方案。

First, to simplify everything, create a temporary table: 首先,为了简化一切,创建一个临时表:

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;

Now work with #temp_table . 现在使用#temp_table First, let's get the unique 'sample_id` values: 首先,让我们获得唯一的“ 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;

And now, let's build the pivot table: 现在,让我们构建数据透视表:

--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;

Hope this helps. 希望这可以帮助。


Reference: 参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM