2010-12-14 13 views
3

私はこのシナリオを持っている:未知数の行を別の行に結合するにはどうすればよいですか?

表A:

--------------- 
ID| SOME_VALUE| 
--------------- 
1 | 123223 | 
2 | 1232ff | 
--------------- 

表B:

------------------ 
ID | KEY | VALUE | 
------------------ 
23 | 1 | 435 | 
24 | 1 | 436 | 
------------------ 

キーが表AのIDへの参照です。

表Cは、表中に発見されたどのように多くのマッチング値に応じて、列の任意の番号を持つことができるはず

表C

------------------------- 
ID| SOME_VALUE| | | 
------------------------- 
1 | 123223 |435 |436 | 
2 | 1232ff | | | 
------------------------- 
:私は次のような結果を得るように、私は何とかこれらのテーブルを結合することができますB.

ここで私が何をしているのか十分に説明してください。

ありがとうございました。

+0

私は個人的にあなたのデザインを変更します。キー値テーブルは、効率的かつ正しく動作するためには非常に難しい設計です。キー値ペアが本当に必要な場合は、リレーショナルデータベースがそれらを格納するのに最適な場所ではないかもしれません。 noSQLデータベースが良い選択かもしれません。 – HLGEM

+0

はい、私はこれがこの問題を解決するための素晴らしい方法ではないことを知っていますが、私はこれを一度だけ必要とし、どのアプリケーションにも実装されません。 – picknick

答えて

3

これを実行するには、動的PIVOT句を使用する必要があります。

EDIT:

[OK]をので、私はいくつかは遊んで、次のサンプルデータに基づいて行ってきた:

Create Table TableA 
(
IDCol int, 
SomeValue varchar(50) 
) 
Create Table TableB 
(
IDCol int, 
KEYCol int, 
Value varchar(50) 
) 

Insert into TableA 
Values (1, '123223') 
Insert Into TableA 
Values (2,'1232ff') 
Insert into TableA 
Values (3, '222222') 

Insert Into TableB 
Values(23, 1, 435) 
Insert Into TableB 
Values(24, 1, 436) 

Insert Into TableB 
Values(25, 3, 45) 
Insert Into TableB 
Values(26, 3, 46) 

Insert Into TableB 
Values(27, 3, 435) 
Insert Into TableB 
Values(28, 3, 437) 

あなたは、次の動的SQLを実行することができます。

declare @sql varchar(max) 
declare @pivot_list varchar(max) 
declare @pivot_select varchar(max) 

Select 
     @pivot_list = Coalesce(@Pivot_List + ', ','') + '[' + Value +']', 
     @Pivot_select = Coalesce(@pivot_Select, ', ','') +'IsNull([' + Value +'],'''') as [' + Value + '],' 
From 
(
Select distinct Value From dbo.TableB 
)PivotCodes 

Set @Sql = ' 
;With p as (

Select a.IdCol, 
     a.SomeValue, 
     b.Value 
From dbo.TableA a 
Left Join dbo.TableB b on a.IdCol = b.KeyCol 
) 
Select IdCol, SomeValue ' + Left(@pivot_select, Len(@Pivot_Select)-1) + ' 
From p 
Pivot (Max(Value) for Value in (' + @pivot_list + ' 
     ) 
    )as pvt 
' 

exec (@sql) 

これはあなたに次のような出力が得られます。

alt text

これは、維持するために悪夢になり、現時点では動作しますが。私はこれらの結果を他のどこかで達成しようと勧めています。つまりSQLではありません!

幸運を祈る!

+0

ありがとう!私は「SQLではない」という点に同意しますが、これはただのことでした。 – picknick

0

これは、データベースが行うべきではないもののようです。まず、テーブルには、格納する項目に応じて任意の数のカラムを持つことはできません。とにかく最大数の値を設定する必要があります。このセル(または同様のピボットのようなソリューション)の値としてカンマ区切り値を使用することで、この問題を回避できます。

ただし、あなたがテーブルAとテーブルBを持っていれば;私はそれらの2つのテーブルを維持することをお勧めします。彼らはかなり正規化されているようです。入力a.some_valueが与えられたb.valueのリストが必要な場合は、次のsqlクエリでそのリストが得られます。

a、bからb.valueを選択します。b.key = a.id a.some_value = 'INPUT_VALUE';

2

Barryが十分に説明したように、動的ピボットを使用して複数の列を取得することは可能です。

すべての値を1つのVARCHAR列に入れることを除いて、必要なものを得るためのソリューションがあります。これらの結果を分割することができれば、必要なものを手に入れることができます。

このメソッドは、値の列から文字列を作成するために使用できるSQL Server 2005のトリックです。

CREATE TABLE #TableA (
    ID INT, 
    SomeValue VARCHAR(50) 
); 
CREATE TABLE #TableB (
    ID INT, 
    TableAKEY INT, 
    BValue VARCHAR(50) 
); 

INSERT INTO #TableA VALUES (1, '123223'); 
INSERT INTO #TableA VALUES (2, '1232ff'); 
INSERT INTO #TableA VALUES (3, '222222'); 

INSERT INTO #TableB VALUES (23, 1, 435); 
INSERT INTO #TableB VALUES (24, 1, 436); 
INSERT INTO #TableB VALUES (25, 3, 45); 
INSERT INTO #TableB VALUES (26, 3, 46); 
INSERT INTO #TableB VALUES (27, 3, 435); 
INSERT INTO #TableB VALUES (28, 3, 437); 

SELECT 
    a.ID 
    ,a.SomeValue 
    ,RTRIM(bvals.BValues) AS ValueList 
FROM #TableA AS a 
OUTER APPLY (
    -- This has the effect of concatenating all of 
    -- the BValues for the given value of a.ID. 
    SELECT b.BValue + ' ' AS [text()] 
    FROM #TableB AS b 
    WHERE a.ID = b.TableAKEY 
    ORDER BY b.ID 
    FOR XML PATH('') 
) AS bvals (BValues) 
ORDER BY a.ID 
; 

あなたは、結果としてこれを取得します:

ID SomeValue ValueList 
--- ---------- -------------- 
1 123223  435 436 
2 1232ff  NULL 
3 222222  45 46 435 437 
+0

私は実際にあなたの解決策に行くことになったが、受け入れられた答えは私の元の質問に近づいた。ありがとう! – picknick

+0

それは大丈夫です。私は受け入れられた答えに見られるような種類のソリューションを作りました。作者の言うとおり、それは効果的ですが、それはメンテナンスの悪夢です。 – eksortso

関連する問題