2017-11-30 3 views
0

Lange Zeit lurker, erste Frage Fragesteller ...Wie teilt man eine mehrwertige Spalte mit Trennzeichen in mehrere Zeilen auf?

Ich habe keine Antwort auf dieses spezifische Problem gefunden, obwohl es vertraut scheint, bin ich mir sicher.

Ich habe eine Tabelle mit einer Spalte, die eine Semikolon getrennte Liste von Werten enthält. Die Tabelle ist eine Liste von Anwendungen zusammen mit den Servern, die dieser Anwendung zugeordnet sind. Die Liste der Server ist durch Semikolon getrennt, aber in serverId; serverName für x Anzahl der Server aufgeteilt - es gibt einige Anwendungen, die mit hunderten von Servern verknüpft sind, einige sind mit 1 verknüpft und einige sind mit 0 verknüpft Diese Server-Spalte wird für jeden eindeutigen Server in Zeilen aufgeteilt, einschließlich der ID aus der Tabelle sowie der Spalten serverId und serverName.

Daten sieht zur Zeit ähnliche

applicationId\Servers 1\serverId1;serverName1 2\serverId2;serverName2;serverId3;serverName3 3\serverId1;serverName1;serverId5;serverName5;serverId8;serverName8 4\serverId9;serverName9 5\

Ich möchte eine neue Tabelle mit dem applicationId, serverId und server Spalten erstellen, wie folgt aus:

applicationId\serverId\serverName 1\serverId1\serverName1 2\serverId2\serverName2 2\serverId3\serverName3 3\serverId1\serverName1 3\serverId5\serverName5 3\serverId8\serverName8 4\serverId9\serverName9 5\

Alternativ , wenn ich nur die serverId in eine Tabelle mit der ApplicationId bekommen könnte, wäre es hilfreich, da ich auch eine Tabelle mit serverId und serverName habe.

applicationId\serverId

Ich habe versucht, die Spalte nur Aufspaltung ';' aber das erzeugt nicht sehr hilfreich Ausgabe wie folgt aus:

applicationId\serverColumn 1\serverId1 1\serverName1 2\serverId2 2\serverName2 2\serverId3 2\serverName3 ....

Jede Hilfe wäre sehr geschätzt.

+1

Das hier größte Problem ist, dass Sie begrenzte Daten zu speichern. Jetzt möchten Sie von einer begrenzten Version zu einer anderen Version wechseln. Das ist kein guter Plan. Sie sollten dies stattdessen in ein normalisiertes Design verschieben. –

+0

Ihr Problem besteht darin, dass Sie eine 'one to many' Relation in nur einer Tabelle gespeichert haben. Repariere das, indem du deine Daten normalisierst und nicht nur dieses Problem, sondern alle zukünftigen Probleme damit verschwinden wirst – GuidoG

+0

Leider ist dies der einzige Weg, wie ich die Daten konsumieren kann, sonst würde ich es definitiv nicht so gestalten. – MattAtWork

Antwort

2

Dies ist nur eine schreckliche Datenstruktur um es gelinde auszudrücken. Aber es ist möglich, Jeff Modens Splitter zu verwenden. http://www.sqlservercentral.com/articles/Tally+Table/72993/ Ich weiß, Sie sagen, Sie haben einen Splitter, aber wenn es eine Schleife oder rekursive cte hat, müssen Sie es wegwerfen für einen Satz basiert wie Jeff.

Hier ist ein voll funktionsfähiges Beispiel, wie Sie seinen Splitter nutzen können, um diese Arbeit zu machen.

declare @Something table 
(
    ApplicationID int 
    , ServerInfo varchar(100)) 
insert @Something 
(
    ApplicationID 
    , ServerInfo 
) values 
(1, 'serverId1;serverName1') 
, (2, 'serverId2;serverName2;serverId3;serverName3') 
, (3, 'serverId1;serverName1;serverId5;serverName5;serverId8;serverName8') 
, (4, 'serverId9;serverName9') 
; 

with ServerIDs as 
(
    select s.ApplicationID 
     , ServerID = case when x.ItemNumber % 2 = 1 then x.Item end 
     , x.ItemNumber 
    from @Something s 
    cross apply dbo.DelimitedSplit8K(s.ServerInfo, ';') x 
    where x.ItemNumber % 2 = 1 
) 
, ServerNames as 
(
    select s.ApplicationID 
     , ServerName = case when x.ItemNumber % 2 = 0 then x.Item end 
     , x.ItemNumber 
    from @Something s 
    cross apply dbo.DelimitedSplit8K(s.ServerInfo, ';') x 
    where x.ItemNumber % 2 = 0 
) 

select si.ApplicationID 
    , si.ServerID 
    , sn.ServerName 
from ServerIDs si 
join ServerNames sn on sn.ApplicationID = si.ApplicationID and si.ItemNumber + 1 = sn.ItemNumber 

Das gibt:

ApplicationID ServerID ServerName 
1    serverId1 serverName1 
2    serverId2 serverName2 
2    serverId3 serverName3 
3    serverId1 serverName1 
3    serverId5 serverName5 
3    serverId8 serverName8 
4    serverId9 serverName9 
+0

Das hat den Trick gemacht! Vielen Dank! Ich hatte nicht daran gedacht, die Modulus-Funktion zu benutzen, um das zu erreichen, aber es macht Sinn und funktioniert großartig. – MattAtWork

+1

Froh, dass geholfen hat. Aber ernsthaft ... versuchen Sie, einen besseren Ansatz zu finden, als das Speichern von begrenzten Daten. –

Verwandte Themen