2016-06-08 205 views
1

如何使用SQL查詢將SQL Server表meterdata轉換爲Result_Table支持sql server表

MeterData表存儲的功率和頻率,並具有主鍵(meterno, date, timeblock)和meterno列有變量號。值。

MeterData表:

meterno date  timeblock power frequency  
-------------------------------------------------- 
89  1-Apr-16 1  500  50.02  
89  1-Apr-16 2  100  49.99  
90  1-Apr-16 1  200  50.02  
90  1-Apr-16 2  300  49.89  

Result_Table

date timeblock 89_power 90_power 89_frequency 90_frequency 
1-Apr-16 1  500  200  50.02  50.02 
1-Apr-16 2  100  300  49.99  49.89 

爲簡單起見讓我們假設meterno列具有固定的沒有。值(89,90)。我正在嘗試下面的查詢,但沒有得到結果。有人可以編輯查詢,以便輸出結果如上所述。最好還是使用數據透視查詢來回答。查詢是

SELECT 
* 
FROM 
(
    SELECT 
* 
    FROM meterdata 
) AS P 
PIVOT 
(
    sum (power) FOR meterno IN (89, 90) 
) AS pv1 
PIVOT 
(
    sum (frequency) FOR meterno IN (89, 90) 
) AS pv2 

GO 

回答

0

動態SQL會幫助你(我用##MeterDatatempdb您必須使用實際的表格和數據庫名稱)。將處理源表中的任意數量的列。一些評論:

  • 您需要CASTCONVERT所有列到一個類型(我在@p變量使用nvarchar(10));
  • 我排除了列meterno,date,timeblock,因爲在您的數據集中沒有使用參數;
  • 您可以在執行之前PRINT @sql查看已執行的內容。

下面是查詢:

DECLARE @p nvarchar(max), @c nvarchar(max), @s nvarchar(max), @sql nvarchar(max) 

--That will get you this: 
--,CAST([power] as nvarchar(10)) [power],CAST([frequency] as nvarchar(10)) [frequency] 
SELECT @p = (
SELECT ',CAST(' + QUOTENAME(COLUMN_NAME) + ' as nvarchar(10)) '+ QUOTENAME(COLUMN_NAME) 
FROM tempdb.INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = N'##MeterData' AND COLUMN_NAME NOT IN ('meterno','date','timeblock') 
FOR XML PATH('') 
) 
--[power],[frequency] 
SELECT @c = STUFF((
SELECT ',' + QUOTENAME(COLUMN_NAME) 
FROM tempdb.INFORMATION_SCHEMA.COLUMNS 
WHERE TABLE_NAME = N'##MeterData' AND COLUMN_NAME NOT IN ('meterno','date','timeblock') 
FOR XML PATH('')),1,1,'') 
--[frequency89],[frequency90],[power89],[power90] 
SELECT @s = STUFF((
SELECT DISTINCT ','+QUOTENAME(COLUMN_NAME + CAST(meterno as nvarchar(10))) 
FROM ##MeterData m 
CROSS JOIN (
    SELECT COLUMN_NAME 
    FROM tempdb.INFORMATION_SCHEMA.COLUMNS 
    WHERE TABLE_NAME = N'##MeterData' AND COLUMN_NAME NOT IN ('meterno','date','timeblock') 
) as p 
FOR XML PATH('')),1,1,'') 
--Put it all in dynamic query 
SELECT @sql = ' 
SELECT * 
FROM (
    SELECT [date], 
      timeblock, 
      params + CAST(meterno as nvarchar(10)) as params, 
      [values] 
    FROM (
     SELECT meterno, 
       [date], 
       timeblock' 
       [email protected]+ 
       ' 
     FROM ##MeterData 
     ) as p 
    UNPIVOT (
     [values] FOR params IN ('[email protected]+') 
    ) as unpvt 
) as p2 
PIVOT (
    MAX([Values]) FOR params IN ('[email protected]+') 
) as pvt' 
--And execute 
EXEC sp_executesql @sql 

輸出:

date  timeblock frequency89 frequency90 power89 power90 
2016-04-01 1   50.02  50.02  500  200 
2016-04-01 2   49.99  49.89  100  300 
+0

謝謝@ gofr1,以獲得精彩的答案。我試圖從最近兩天完成這一點,並且在短短的幾分鐘內就已經解決了。 –

0

下面是一個支點查詢,你可以嘗試不使用SQL Server PIVOT操作:

SELECT date, timeblock 
    SUM(CASE WHEN meterno=89 THEN power  ELSE 0 END) AS meterno-89_power, 
    SUM(CASE WHEN meterno=90 THEN power  ELSE 0 END) AS meterno-90_power, 
    SUM(CASE WHEN meterno=89 THEN frequency ELSE 0 END) AS meterno-89_frequency, 
    SUM(CASE WHEN meterno=90 THEN frequency ELSE 0 END) AS meterno-89_frequency 
FROM MeterData 
GROUP BY date, timeblock 
+0

感謝蒂姆早日答覆。但我沒有提到,meterno列是可變的,即它可以有任何值,如89,90,91,95 ..... –

+0

如果'meterno'只有一組固定的值,那麼只需修改我的查詢相應地通過增加額外的'CASE'語句。如果列的數量很大或可變,那麼您將需要使用動態SQL來處理它。 –

+0

它不是很大,但可變。在這種情況下,我如何使用動態sql?即我想要現成的查詢! –