2011-02-27 12 views
0

私はのようなテーブルがあるとしましょう:私は列垂直選択結果の代わりに水平結果のSQL Serverの

SQRT(sum(a*a)), SQRT(sum(a*b)), SQRT(sum(a*c)), SQRT(sum(a*d)), SQRT(sum(a*e)), 
SQRT(sum(a*f)), SQRT(sum(b*b)), SQRT(sum(b*c)), SQRT(sum(b*d)).... SQRT(sum(f*f)) 
の和の乗算の平方根として何かを計算する必要がある場合

a  b c  d e  f 
--------------------------------- 
1.2 2.3 4.4 5.1 6.7 11.9 
7.2 2.3 4.3 5.1 4.7 3.9 
1.9 5.3 3.3 5.1 3.7 8.9 
5.2 2.7 7.4 9.1 1.7 2.9 

結果:代わりの

id result operation 
----------------------------- 
1 x  a*a 
2 y  a*b 
... ...  ... 
n z  f*f 

a*a  a*b ...  f*f 
---------------------------- 
x  y ...  z 

現在のクエリが

SELECT SQRT(sum(a*a)) AS a*a, SQRT(sum(a*b)) AS a*b, ... , SQRT(sum(f*f)) AS f*f 
FROM Sometable 
+0

ですこれは[OK]をhttp://stackoverflow.com/questions/5111412/multi-threading-in-sql-server – Thomas

答えて

1
DECLARE @T TABLE(
id INT PRIMARY KEY, 
a FLOAT, 
b FLOAT, 
c FLOAT, 
d FLOAT, 
e FLOAT, 
f FLOAT 
) 

INSERT INTO @T 
SELECT * FROM (VALUES 
(1, 1.2,2.3,4.4,5.1,6.7,11.9), 
(2, 7.2,2.3,4.3,5.1,4.7,3.9), 
(3, 1.9,5.3,3.3,5.1,3.7,8.9), 
(4, 5.2,2.7,7.4,9.1,1.7,2.9)) T(id,a,b,c,d,e, f) 

;WITH U AS 
(
SELECT * 
FROM @T 
UNPIVOT (o FOR col IN (a,b,c,d,e, f)) unpvt 
) 
SELECT u1.col + '*' + u2.col as operation, SQRT(sum(u1.o*u2.o)) AS result 
FROM U u1 JOIN U u2 ON u1.id=u2.id AND u1.col <= u2.col 
GROUP BY u2.col, u1.col 
ORDER BY u2.col, u1.col 
+0

少し説明してください:@ UNPIVOT(o、col、(b、c、d、e、f)のために)unpvt )正確に何をしますか? – cMinor

+1

@ darkcminor - 列構造を行に変換します(基本的には、NormalizedInputsと同じですが、6の代わりに1つのパスを使用する以外は、他の答えにあります)。もしあなたが 'SELECT * FROM @T UNPIVOT(colin(a、b、c、d、e、f))unpvt'を実行しているのであれば、何が起きているのかは明らかです。 Thomasの答えに対するあなたのコメントから、基本データをこのフォームに入れることは、動的な列で作業するのではなく、最も簡単な方法かもしれません。 –

+0

あなたの解決策は私のproblem.Butにもっと合っていると思いますが、あなたには別の質問があります。x * yとy * xの場合(例えばa * bとb * a)を検出することは可能ですか?同じですから、私はそれらを再び計算するのを避けますか? – cMinor

1
With Inputs As 
    (
    Select 1 As RowNum, 1.2 As a, 2.3 As b, 4.4 As c, 5.1 As d, 6.7 As e, 11.9 As f 
    Union All Select 2, 7.2, 2.3, 4.3, 5.1, 4.7, 3.9 
    Union All Select 3, 1.9, 5.3, 3.3, 5.1, 3.7, 8.9 
    Union All Select 4, 5.2, 2.7, 7.4, 9.1, 1.7, 2.9 
    ) 
    , NormalizedInputs As 
    (
    Select RowNum, 'a' As ColName, a As Value From Inputs 
    Union All Select RowNum, 'b', b From Inputs 
    Union All Select RowNum, 'c', c From Inputs 
    Union All Select RowNum, 'd', d From Inputs 
    Union All Select RowNum, 'e', e From Inputs 
    Union All Select RowNum, 'f', f From Inputs 
    ) 
Select N1.RowNum, Sqrt(Sum(N1.Value * N2.Value)) 
From NormalizedInputs As N1 
    Left Join NormalizedInputs As N2 
     On N2.RowNum = N1.RowNum 
      And N2.ColName >= N1.ColName 
Group By N1.RowNum 
+0

の重複のように思えますしかし、もっと多くの列がある場合はどうしますか?これを行うより一般的な方法はありますか? – cMinor

+0

私が持っている問題は、60以上の列がある可能性があるということです。あなたが提供する解決策は正しいですが、それを一般化するには?? – cMinor

+1

@ darkcminor - SQLは、動的列の生成用に設計されておらず、そのためのメカニズムもありません。この問題を解決する唯一の方法は、列を静的に書き出すか、動的SQLを使用することです。動的SQLを使用する場合は、T-SQLで行うべきではありません。中間層コンポーネントでそれを行う必要があります。 – Thomas