Erstellen Sie eine Tabelle mit eindeutigen Werten aus einer anderen Tabelle

Ich verwende MS SQL server Management Studio. Ich habe tisch –

+--------+----------+ | Num_ID | Alpha_ID | +--------+----------+ | 1 | A | | 1 | B | | 1 | C | | 2 | B | | 2 | C | | 3 | A | | 4 | C | | 5 | A | | 5 | B | +--------+----------+ 

Ich möchte eine weitere Tabelle mit 2 Spalten aus dieser Tabelle erstellen, so dass column_1 eindeutige Werte in Num_ID gibt (dh 1,2,3,4 und so weiter) und column_2 gibt eindeutige Werte in Alpha_ID (A, B, C und so weiter) .

Aber wenn ein Alphabet bereits aufgetreten ist, sollte es nicht wieder auftreten. Also die Ausgabe wird so etwas sein –

 Col_1 Col_2 ================ 1 - A ---------------- 2 - B ---------------- 3 - NULL (as A has been chosen by 1, it cannot occur next to 3) ---------------- 4 - C ---------------- 5 - NULL (both 5 A and 5 B cannot be chosen as A and B were picked up by 1 and 2) ---------------- 

Hoffe das macht Sinn. Ich möchte klarstellen, dass die IDs in der Eingabetabelle nicht numerisch sind, wie ich gezeigt habe, aber sowohl Num_ID als auch Alpha_ID sind komplexe characterfolgen. Ich habe sie zu 1,2,3, … und A, B, C …. für die Zwecke dieser Frage vereinfacht

Ich glaube nicht, dass dies ohne einen Cursor getan werden könnte. Ich habe noch einige Zeilen zu Ihren Beispieldaten hinzugefügt, um zu testing, wie es mit anderen Fällen funktioniert.

Die Logik ist geradeaus. Zuerst get eine list aller verschiedenen Werte von Num_ID . Dann durchschleifen und mit jeder Iteration eine Zeile zur Zieltabelle hinzufügen. Um den Alpha_ID Wert zu bestimmen, werde ich den EXCEPT Operator verwenden, der alle verfügbaren Alpha_ID Werte für die aktuelle Num_ID aus der Quellentabelle übernimmt und von ihnen alle zuvor verwendeten Werte entfernt.

Es ist möglich, das INSERT zu schreiben, ohne explizite Variable @CurrAlphaID , aber es sieht ein bisschen sauberer mit Variable aus.

Hier ist SQL Fiddle .

 DECLARE @TSrc TABLE (Num_ID varchar(10), Alpha_ID varchar(10)); INSERT INTO @TSrc (Num_ID, Alpha_ID) VALUES ('1', 'A'), ('1', 'B'), ('1', 'C'), ('2', 'B'), ('2', 'C'), ('3', 'A'), ('3', 'C'), ('4', 'A'), ('4', 'C'), ('5', 'A'), ('5', 'B'), ('5', 'C'), ('6', 'D'), ('6', 'E'); DECLARE @TDst TABLE (Num_ID varchar(10), Alpha_ID varchar(10)); DECLARE @CurrNumID varchar(10); DECLARE @CurrAlphaID varchar(10); DECLARE @iFS int; DECLARE @VarCursor CURSOR; SET @VarCursor = CURSOR FAST_FORWARD FOR SELECT DISTINCT Num_ID FROM @TSrc ORDER BY Num_ID; OPEN @VarCursor; FETCH NEXT FROM @VarCursor INTO @CurrNumID; SET @iFS = @@FETCH_STATUS; WHILE @iFS = 0 BEGIN SET @CurrAlphaID = ( SELECT TOP(1) Diff.Alpha_ID FROM ( SELECT Src.Alpha_ID FROM @TSrc AS Src WHERE Src.Num_ID = @CurrNumID EXCEPT SELECT Dst.Alpha_ID FROM @TDst AS Dst ) AS Diff ORDER BY Diff.Alpha_ID ); INSERT INTO @TDst (Num_ID, Alpha_ID) VALUES (@CurrNumID, @CurrAlphaID); FETCH NEXT FROM @VarCursor INTO @CurrNumID; SET @iFS = @@FETCH_STATUS; END; CLOSE @VarCursor; DEALLOCATE @VarCursor; SELECT * FROM @TDst; 

Ergebnis

 Num_ID Alpha_ID 1 A 2 B 3 C 4 NULL 5 NULL 6 D 

Der Index auf (Num_ID, Alpha_ID) auf der Quellentabelle würde helfen. Der Index auf (Alpha_ID) auf der (Alpha_ID) würde auch helfen.

Ich glaube ich habe etwas nicht durch eine Rekursion gemacht (Cursor oder eine Weile)

Zuerst habe ich einen Tisch mit Zeilen erstellt.

 create table #tmptest ( Num_ID int , Alpha_ID varchar(50) ) insert into #tmptest (Num_ID, Alpha_ID) values (1,'A'), (1,'B'), (1,'C'), (2,'B'), (2,'C'), (3,'A'), (4,'C'), (5,'A'), (5,'B') // this one, with row column SELECT ROW_NUMBER() OVER (PARTITION BY Num_ID ORDER BY Num_ID ASC) as row , * INTO #tmp_withrow FROM #tmptest 

und das waren die Ergebnisse

Bildbeschreibung hier eingeben

Schließlich habe ich eine innere Abfrage gemacht (könnte vielleicht eine linke Verbindung oder besser sein).

 SELECT DISTINCT Num_ID , ( SELECT TOP 1 Alpha_ID FROM #tmp_withrow in1 WHERE in1.Num_ID = t.Num_ID AND in1.Alpha_ID NOT IN ( SELECT Alpha_ID FROM #tmp_withrow in2 WHERE in2.Num_ID < in1.Num_ID AND in2.row = 1 ) ORDER BY in1.Num_ID ASC ) AS [NonRepeatingAlpha] from #tmptest t 

und das waren die Ergebnisse

Bildbeschreibung hier eingeben

Anmerkung: Ich habe eine Fahne ( row ) erstellt, die es Ihnen ermöglicht, alle weniger als die IDs, die Sie in ( in2.Num_ID < in1.Num_ID ) in2.Num_ID < in1.Num_ID dann herauszufinden, welche Buchstaben wo bereits verwendet ( in2.row = 1 ) und dann Alle Buchstaben auswählen / vermeiden, die bereits von der anderen Num_ID verwendet wurden (

 WHERE in1.Num_ID = t.Num_ID AND in1.Alpha_ID NOT IN ( SELECT Alpha_ID FROM #tmp_withrow in2 WHERE in2.Num_ID < in1.Num_ID AND in2.row = 1 

)

Ich hoffe das hilft. Vielen Dank!