2013-02-01 108 views
0

我有N列的表:SQL Server查詢 - 透視後n列

TABLE: 
TB_SAMPLE 

COLUMNS: 

VALUE_A 
COUNT_A 
VALUE_B 
COUNT_B 
VALUE_C 
COUNT_C 
VALUE_D 
COUNT_D 
VALUE_E 
COUNT_E 
VALUE_F 
COUNT_F 
VALUE_G 
COUNT_G 
VALUE_H 
COUNT_H 
VALUE_I 
COUNT_I 

我想回到這樣的:

'Value', 'Count' 
A, 1 -- this is the first and the second column 
B, 3 -- this is the third and the fourth column 
C, 4 -- this is the fifth and sixth column 

等前鋒。我已經用UNION ALL子句嘗試了多個select,但由於我返回了很多記錄,所以速度並不快。有沒有更好的方法來'旋轉'這個表2列?

謝謝。

+0

如何計數爲每列或價值的計算? – TechDo

+0

你可以從你的表中發佈一些示例數據嗎?很難說出理想的結果。 – Taryn

+0

@techdo它是另一個保存這些信息的應用程序 –

回答

3

這也可以使用CROSS APPLYVALUES聲明進行:

SELECT vals, counts 
FROM temp t 
CROSS APPLY 
(
    VALUES 
     (value_a, count_a), 
     (value_b, count_b), 
     (value_c, count_c), 
     (value_d, count_d), 
     (value_e, count_e), 
     (value_f, count_f), 
     (value_g, count_g), 
     (value_h, count_h) 
) x (vals, counts); 

SQL Fiddle with Demo

這裏是解釋如何做到這一點(需要註冊)的一篇文章:

http://www.sqlservercentral.com/articles/CROSS+APPLY+VALUES+UNPIVOT/91234/

+0

不錯的解決方案。雖然,你發佈的鏈接需要註冊,這有點痛苦...... – codingbadger

1

你可以UNPIVOT,然後轉動數據,它可能會表現得更好:

DECLARE @T TABLE 
( VALUE_A INT, COUNT_A INT, VALUE_B INT, COUNT_B INT, VALUE_C INT, COUNT_C INT, VALUE_D INT, COUNT_D INT, VALUE_E INT, 
    COUNT_E INT, VALUE_F INT, COUNT_F INT, VALUE_G INT, COUNT_G INT, VALUE_H INT, COUNT_H INT, VALUE_I INT, COUNT_I INT 
); 
INSERT @T VALUES (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1); 

WITH D AS 
( SELECT Category = SUBSTRING(B, 7, LEN(B)), [Type] = 'Value', A 
    FROM @T 
      UNPIVOT 
      ( A 
       FOR B IN ([VALUE_A], [VALUE_B], [VALUE_C], [VALUE_D], [VALUE_E], [VALUE_F], [VALUE_G], [VALUE_H], [VALUE_I]) 
      ) upvt 
    UNION ALL 
    SELECT Category = SUBSTRING(B, 7, LEN(B)), [Type] = 'Count', A 
    FROM @T 
      UNPIVOT 
      ( A 
       FOR B IN ([COUNT_A], [COUNT_B], [COUNT_C], [COUNT_D], [COUNT_E], [COUNT_F], [COUNT_G], [COUNT_H], [COUNT_I]) 
      ) upvt 
) 
SELECT * 
FROM D 
     PIVOT 
     ( SUM(A) 
      FOR [Type] IN ([Value], [Count]) 
     ) pvt; 

你也可以在需要通過查詢列名的系統視圖做到這一點動態。

附錄

剛剛意識到這可能是與一個連接而不是UNION和樞軸來實現,我想像的加入,因爲它消除了PIVOT操作將有更好的表現。我仍然建議您同時測試兩者,以查看哪種數據最適合您。

WITH Val AS 
( SELECT Category = SUBSTRING(B, 7, LEN(B)), A 
    FROM @T 
      UNPIVOT 
      ( A 
       FOR B IN ([VALUE_A], [VALUE_B], [VALUE_C], [VALUE_D], [VALUE_E], [VALUE_F], [VALUE_G], [VALUE_H], [VALUE_I]) 
      ) upvt 
), Co AS 
( SELECT Category = SUBSTRING(B, 7, LEN(B)), A 
    FROM @T 
      UNPIVOT 
      ( A 
       FOR B IN ([COUNT_A], [COUNT_B], [COUNT_C], [COUNT_D], [COUNT_E], [COUNT_F], [COUNT_G], [COUNT_H], [COUNT_I]) 
      ) upvt 
) 
SELECT val.Category, 
     [Value] = val.A, 
     [Count] = co.A 
FROM val 
     INNER JOIN co 
      ON co.Category = val.Category; 
1

這裏是另一種方式來做到這一點(如果我理解正確你的問題)

declare @table table 
(
value_a varchar(10), 
count_a int, 
value_b varchar(10), 
count_b int, 
value_c varchar(10), 
count_c int, 
value_d varchar(10), 
count_d int, 
value_e varchar(10), 
count_e int, 
value_f varchar(10), 
count_f int, 
value_g varchar(10), 
count_g int, 
value_h varchar(10), 
count_h int 
) 

Insert Into @table 
Select 'value a',675, 
     'value b',646, 
     'value c',13, 
     'value d',22, 
     'value e',768, 
     'value f',223, 
     'value g',66, 
     'value h',55 


SELECT vals, 
     counts 
FROM 
    (
    SELECT * 
    FROM @table 
    ) p 
UNPIVOT 
    (vals FOR cols IN 
     ([value_a],[value_b],[value_c],[value_d], [value_e],[value_f],[value_g],[value_h]) 
)AS unpvtValues 
Unpivot 
    (
     counts for counters in ([count_a],[count_b],[count_c], [count_d],[count_e],[count_f],[count_g],[count_h]) 
    ) as unpvtCounts 
where Right(cols, 2) = right(counters, 2) 

編輯

如果你想使用一些動態SQL,那麼你可以使用這個選項(這會在你的數據庫相應表,而不是使用表變量)

create Table dbo.TempTable 
(
value_a varchar(10), 
count_a int, 
value_b varchar(10), 
count_b int, 
value_c varchar(10), 
count_c int, 
value_d varchar(10), 
count_d int, 
value_e varchar(10), 
count_e int, 
value_f varchar(10), 
count_f int, 
value_g varchar(10), 
count_g int, 
value_h varchar(10), 
count_h int 
) 

Insert Into dbo.TempTable 
Select 'value a',675, 
     'value b',646, 
     'value c',13, 
     'value d',22, 
     'value e',768, 
     'value f',223, 
     'value g',66, 
     'value h',55 


Declare @ValueCols varchar(max), 
     @CountCols varchar(max), 
     @sql varchar(max) 


Select @ValueCols = Coalesce(@ValueCols + ', ','') + '[' + Column_Name +']' 
From INFORMATION_SCHEMA.COLUMNS 
Where TABLE_NAME = 'TempTable' 
And COLUMN_NAME Like 'Value%' 

Select @CountCols = Coalesce(@CountCols + ', ','') + '[' + Column_Name +']' 
From INFORMATION_SCHEMA.COLUMNS 
Where TABLE_NAME = 'TempTable' 
And COLUMN_NAME Like 'Count%' 


Set @sql = 'SELECT vals, 
     counts 
FROM 
    (
    SELECT * 
    FROM dbo.TempTable 
    ) p 
    UNPIVOT 
    (vals FOR cols IN 
     (' + @ValueCols +') 
)AS unpvtValues 
Unpivot 
    (
     counts for counters in (' + @CountCols + ') 
    ) as unpvtCounts 
where Right(cols, 2) = right(counters, 2)' 


Execute (@sql) 

drop table TempTable