# DB: Mehrere Zeilen in einer Zeile zusammenführen



## Maier2100 (29. Sep 2011)

Hallo zusammen,

ich habe eine Java Desktop Anwendung auf Basis einer DB2 SQL Datenbank und muss mehrere Zeilen einer Tabelle mit einer ID in eine Zeile zusammenführen, verwenden kann ich Java code, SQL, Stored Procedures, einfach irgendwas, damit daraus eine Zieltabelle entsteht, dich ich wieder in der Datenbank abspeichern kann für ein Data Mining:

Quelltabelle (Key ist ID+Wert):
ID - Wert
1 - A
1 - B
1 - C
2 - A

Zieltabelle:
ID, WertA, WertB,WertC
1, 1,1,1
2, 1,0,0

Die Werte sind natürlich dynamisch, d.h. es kann sein, dass es von A-X geht, ich muss es also dynamisch machen.
Habt ihr eine Idee?


----------



## Gast2 (29. Sep 2011)

Das einfachste wird wohl sein die Quelltabelle  in Java einzulesen, ein paar Metainformationen zu erstellen und dann eine Zieltabelle zu erzeugen und die Werte abzuspeichern:

1) SELECT DISTINCT Wert From Quelltabelle
2) Speichere die Werte in eine HashMap als Key mit Anzahl 1
3) SELECT * FROM Quelltabelle
4) Update die Hashmap mit den Anzahl der Records für jeden Wert während du über das Resultset iterierst
5) Schreibe ein SQL das aus den Keys der HashMap Spaltennamen erzeugt
6) Inserte in die neue Tabelle die Werte aus der HashMap


----------



## Maier2100 (29. Sep 2011)

fassy hat gesagt.:


> Das einfachste wird wohl sein die Quelltabelle  in Java einzulesen, ein paar Metainformationen zu erstellen und dann eine Zieltabelle zu erzeugen und die Werte abzuspeichern:
> 
> 1) SELECT DISTINCT Wert From Quelltabelle
> 2) Speichere die Werte in eine HashMap als Key mit Anzahl 1
> ...



Dann sind die Daten der Quelltabelle alle in der Hashmap und damit im RAM, sehe ich das richtig?
Das wird wohl problematisch, da die Tabelle deutlich komplexer und größer ist als in meinem Beispiel.

Ich habe gerade den SQL Pivot Befehl entdeckt, aber das scheint nicht das richtige für mein Problem oder?


----------



## Gast2 (29. Sep 2011)

Dann nimmst du statt einer HashMap eine Tabelle in deiner DB 

SQL Pivot könnte auch gehn, habe allerdings nie das Vergnügen mit gehabt da unsere Oracles das nicht konnten.


----------



## bronks (29. Sep 2011)

Maier2100 hat gesagt.:


> ... Habt ihr eine Idee?


Mach es mit SQL. Mit T-SQL könnte es etwa so aussehen:


```
DECLARE @id varchar(20)
DECLARE @alteid varchar(20)
DECLARE @wert1 varchar(20)
DECLARE @wert2 varchar(20)
DECLARE @wert3 varchar(20)

DECLARE cursor SCROLL CURSOR FOR
	SELECT id, wert FROM quelltabelle order by id und sonstwas anderem

OPEN cursor

FETCH FIRST FROM cursor into @id, @wert

WHILE @@FETCH_STATUS=0 BEGIN

    Hier drinnen etwa sinngemäß:

    Wenn die letzte @id nicht der aktellen @id entspricht
         insert into zieltabelle values (@alteid, @wert1 + ',' +  @wert2 +  ',' + @wert3)
         Leere die Variablen @wert1, @wert2, @wert3

    Wenn @wert1 leer
         @wert1 = @wert
    Wenn @wert2 leer
         @wert2 = @wert
    Wenn @wert3 leer
         @wert3 = @wert

    Merke Dir die @id, welche gerade verarbeitet wurde in @alteid.

   FETCH NEXT FROM cursor into @id, @wert
END

CLOSE cursor
DEALLOCATE cursor
```


----------



## Gast2 (30. Sep 2011)

Das geht allerdings nur wenn du eine feste Anzahl an Spalten hast.

Natürlich kann man die Java Variante auch in T-SQL, PL/SQL oder so nachbilden. Aber ich finde da ist es in Java einfacher auszuprogrammieren.


----------



## bronks (1. Okt 2011)

fassy hat gesagt.:


> Das geht allerdings nur wenn du eine feste Anzahl an Spalten hast.


Das war auch nicht die Anforderung.



fassy hat gesagt.:


> ... Aber ich finde da ist es in Java einfacher auszuprogrammieren.


Das finde ich nicht.


----------



## Gast2 (2. Okt 2011)

bronks hat gesagt.:


> Das war auch nicht die Anforderung.



War es:



Maier2100 hat gesagt.:


> Die Werte sind natürlich dynamisch, d.h. es kann sein, dass es von A-X geht, ich muss es also dynamisch machen.


----------



## bronks (4. Okt 2011)

fassy hat gesagt.:


> War es:
> ... ...


Oh, ja! Hast wohl recht. Hab das ganze etwas anders verstanden.


----------



## mtheiss (5. Okt 2011)

```
create table a (id int, value varchar(10));
```


```
insert into a values (1, 'A'), (1, 'B'), (2, 'C'), (2, 'D'), (2, 'E'), (3, 'F');
```


```
select id, group_concat(value separator ',') as allvalues from a group by id;
```


```
+------+-----------+
| id   | allvalues |
+------+-----------+
|    1 | A,B       |
|    2 | C,D,E     |
|    3 | F         |
+------+-----------+
```


----------



## Gast2 (7. Okt 2011)

Erfüllt die Anforderung auch nicht wirklich 

Ist aber wohl egal da er sich eh nicht mehr melded.


----------

