2010-12-14 4 views
3

Ich habe dieses Szenario:Wie verknüpfe ich eine unbekannte Anzahl von Zeilen mit einer anderen Zeile?

Tabelle A:

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

Tabelle B:

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

KEY ist ein Verweis auf Tabelle A der ID. Kann ich komme irgendwie diese Tabellen so, dass ich folgendes Ergebnis:

Tabelle C

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

Tabelle C sollte jede beliebige Anzahl von Spalten je nachdem, wie viele passenden Werten haben kann, die in der Tabelle zu finden sind B.

Ich hoffe, dass dies genug, um zu erklären, was ich hier bin.

Danke.

+0

ich persönlich Ihr Design ändern würde. Schlüsselwerttabellen sind ein sehr schwieriges Design, um effizient und korrekt arbeiten zu können. Wenn Sie wirklich Schlüsselpaare benötigen, ist eine relationale Datenbank möglicherweise nicht der beste Ort, um sie zu speichern. Eine NoSQL-Datenbank ist möglicherweise eine bessere Wahl. – HLGEM

+0

Ja, ich weiß, dass dies kein guter Weg ist, um dieses Problem zu lösen, aber ich brauchte das nur für eine einmalige Sache und es wird nicht in irgendeiner Anwendung implementiert werden. – picknick

Antwort

3

Sie müssen eine dynamische PIVOT-Klausel verwenden, um dies zu tun.

EDIT:

Ok, damit ich einige herumgespielt und auf der Grundlage der folgenden Beispieldaten getan haben:

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) 

Sie können die folgende dynamische SQL ausführen.

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) 

Dies gibt Ihnen die folgende Ausgabe:

alt text

Obwohl dies im Moment funktioniert es wäre ein Alptraum zu halten sein. Ich würde empfehlen, diese Ergebnisse woanders zu erreichen. nicht in SQL!

Viel Glück!

+0

Danke! Ich stimme dem Punkt "nicht in SQL" zu, aber das war nur für eine einmalige Sache. – picknick

0

Das sieht aus wie etwas, das eine Datenbank nicht tun sollte. Zuerst; Eine Tabelle kann nicht beliebig viele Spalten haben, abhängig davon, was Sie speichern. Sie müssen also trotzdem eine maximale Anzahl von Werten aufstellen. Sie können dies umgehen, indem Sie kommaseparierte Werte als Wert für diese Zelle verwenden (oder eine ähnliche pivot-ähnliche Lösung).

Jedoch; wenn Sie Tabelle A und B haben; Ich empfehle, an diesen beiden Tischen zu bleiben; wie sie scheinen ziemlich normalisiert zu sein. Wenn Sie eine Liste von b.value mit einer Eingabe an einen bestimmten Wert benötigen, gibt die folgende SQL-Abfrage diese Liste an.

Wählen Sie b.value aus a, b wobei b.key = a.id a.some_value = 'INPUT_VALUE';

2

Da Barry ausführlich dargestellt wurde, ist es möglich, mehrere Spalten mit einem dynamischen Pivot zu erhalten.

Ich habe eine Lösung, die Sie bekommen könnte, was Sie brauchen, außer dass es alle Werte in eine einzige VARCHAR-Spalte legt. Wenn Sie diese Ergebnisse teilen können, erhalten Sie, was Sie brauchen.

Diese Methode ist ein Trick in SQL Server 2005, den Sie verwenden können, um eine Zeichenfolge aus einer Spalte mit Werten zu bilden.

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 
; 

Sie werden dies als Ergebnis erhalten:

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

Ich ging tatsächlich mit Ihrer Lösung, aber die akzeptierte Antwort war näher an meiner ursprünglichen Frage. Vielen Dank! – picknick

+0

Das ist in Ordnung. Ich habe die Art von Lösung entwickelt, die in der akzeptierten Antwort gefunden wird, und, wie der Autor sagt, ist es effektiv, aber es ist ein Wartungs-Albtraum. – eksortso

Verwandte Themen