簡體   English   中英

將單個表的多個SQL查詢合並到單獨的列中

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM