2017-05-14 2 views
2

Ich versuche, einige Active Directory-Daten in SQL Server zu bereinigen. Ich habe es geschafft, die rohe LFD-Datei in eine Tabelle zu lesen. Jetzt muss ich einige Attribute bereinigen, in denen Werte über mehrere Zeilen verteilt sind. Ich kann Datensätze identifizieren, die an den vorherigen Datensatz angehängt werden müssen, da sie einen führenden Platz haben.T-SQL: Bereinigen von Daten, Zusammenführen von Zeilen in Spalten

Beispiel:

ID  Record      IsPartOfPrior 
3114  memberOf:      0 
3115  CN=Sharepoint-Members-home  1 
3116  memberOf:      0 
3117  This is       1 
3118  part of the      1 
3119  next line.      1 

Letztlich würde Ich mag die folgende Tabelle haben, erzeugt:

ID   Record 
3114  memberOf:CN=Sharepoint-Members-home 
3116  memberOf:This is part of the next line 

ich es durch einen Cursor schreiben könnte, Setzen von Variablen, die Arbeit mit temporären Tabellen und bevölkerte Tabelle. Aber es muss einen satzbasierten (vielleicht rekursiven?) Ansatz dazu geben?

Ich könnte die STUFF-Methode verwenden, um verschiedene Zeilen miteinander zu kombinieren, aber wie soll ich die verschiedenen Gruppen zusammenfassen? Ich denke, dass ich zuerst Gruppen-IDs pro Datensatz definieren muss und sie dann per Gruppen-ID zusammenfassen muss?

Danke für jede Hilfe.

+0

Tipp: Verwenden 'STUFF' – Sami

+1

Wenn Sie die Daten aus AD vermutlich in Code lesen, dann warum Sie verketten nicht die Werte vor dem db speichern? – Phil

Antwort

0

Batch mit Kommentaren unten. Sollte funktionieren mit SQL Server 2008.

--Here I emulate your table 
DECLARE @yourtable TABLE (ID int, Record nvarchar(max), IsPartOfPrior bit) 

INSERT INTO @yourtable VALUES     
(3114,'memberOf:',0),(3115,'CN=Sharepoint-Members-home',1),(3116,'memberOf:',0),(3117,'This is',1),(3118,'part of the',1),(3119,'next line.',1) 

--Getting max ID 
DECLARE @max_id int 

SELECT @max_id = MAX(ID)+1 
FROM @yourtable 

--We get next prior for each prior record 
--And use STUFF and FOR XML PATH to build new Record 
SELECT y.ID, 
     y.Record + b.Record as Record 
FROM @yourtable y 
OUTER APPLY (
     SELECT TOP 1 ID as NextPrior 
     FROM @yourtable 
     WHERE IsPartOfPrior = 0 and y.ID < ID 
     ORDER BY ID ASC 
    ) as t 
OUTER APPLY (
    SELECT STUFF((
     SELECT ' '+Record 
     FROM @yourtable 
     WHERE ID > y.ID and ID < ISNULL(t.NextPrior,@max_id) 
     ORDER BY id ASC 
     FOR XML PATH('') 
      ),1,1,'') as Record 
) as b 
WHERE y.IsPartOfPrior = 0 

Der Ausgang:

ID   Record 
----------- ----------------------------------------- 
3114  memberOf:CN=Sharepoint-Members-home 
3116  memberOf:This is part of the next line. 

Das funktioniert, wenn ID Zahlen- und aufsteigend sind.

0

Eine weitere Option wenn 2012+

Beispiel

Declare @YourTable Table ([ID] int,[Record] varchar(50),[IsPartOfPrior] int) 
Insert Into @YourTable Values 
(3114,'memberOf:',0) 
,(3115,'CN=Sharepoint-Members-home',1) 
,(3116,'memberOf:',0) 
,(3117,'This is',1) 
,(3118,'part of the',1) 
,(3119,'next line.',1) 

;with cte as (
    Select *,Grp = sum(IIF([IsPartOfPrior]=0,1,0)) over (Order By ID) 
    From @YourTable 
) 
Select ID 
     ,Record = Stuff((Select ' ' +Record From cte Where Grp=A.Grp Order by ID For XML Path ('')),1,1,'') 
From (Select Grp,ID=min(ID)from cte Group By Grp ) A 

Returns

ID  Record 
3114 memberOf: CN=Sharepoint-Members-home 
3116 memberOf: This is part of the next line. 

Wenn es mit der Visualisierung hilft, die CTE Produziert:

ID  Record      IsPartOfPrior Grp << Notice Grp Values 
3114 memberOf:     0    1 
3115 CN=Sharepoint-Members-home 1    1 
3116 memberOf:     0    2 
3117 This is      1    2 
3118 part of the     1    2 
3119 next line.     1    2 
+0

Bitte beachten Sie, dass 'IIF' mit SQL Server 2012 und höher funktioniert. – gofr1

+0

Auch. SUM() OVER() ist ab 2012 .... –

+0

@ gofr1 Sehr wahr, ich hätte das qualifizieren sollen. (machte die Notation) –

Verwandte Themen