Zusammenführen von MYSQL Datensätzen mit PHP und GROUP_CONCAT - Problem

pekudel

Grünschnabel
Hallo!

Ich muss zwei Tabellen in einer MYSQL Datenbank zusammenführen.

Die Tabellen so in etwa aus:

Tabelle 1 (hat 16000 Einträge)
idnameprodukt_ids
1produkt 139120,38129,38127,38191
2produkt 284798,21003,66191,38991

Tabelle 2 ( Hat 45000 Einträge)
idproduct_idseriennummer
139120sn1,sn2,sn3
238129sn4,sn5,sn6
238129sn7,sn8,sn9


Aussehen soll das ganze so:
idnameseriennummer
1produkt 1sn1,sn2,sn3,...
2produkt 2sn7,sn8,sn9,...

Zu Erklärung
Die Spalte "product_ids" in Tabelle 1 enhält (kommagetrennt!) die Schlüssel zu den Seriennummern in der Tabelle 2. product_ids können in den einzelnen Zeilen der Tabelle 1 ident sein - dh. im Datensatz 500 kann product_id 5600 vorkommen, im Datensatz 654 kann product_id 5600 auch vorkommen.
In der Tabelle 2 können meherere Zeilen bzw. Datensätze zu product_id (z.B.) 5600 vorkommen.

Mein Problem
Ich benötige nun ein Script oder eine MYSQL-Funktion, die mir zu jedem Datensatz der Tabelle 1 die Seriennummern aus Tabelle 2 sucht und in einer weiteren Spalte der Tabelle 1 (z.B. "Seriennummer") kommagetrennt zusammensetzt. Sprich wenn in der Tabelle zu einer "product_id" beispielsweise mehrere Datensätze vorhanden sind, sollen diese zusammengeführt werden und kommagetrennt in eine spezielle Spalte der Tabelle 1 eingetragen werden.


Ansätze zur Problemlösung
Habe mit GROUP_CONCAT und einer Schleife ein Script erstellt, welches als erstes alle doppelten Datensätze aus Tabelle 2 zusammenführt. Danach wird jeder Datensatz in Tabelle 1 aufgerufen, mittels foreach die Spalte product_ids aufgelöst (damit ich jede product_id einzeln erhalte) und frage mit einer funktion dann die Zeile in der Tabelle 2 ab, welche die gesuchte product_id enthält.


Leider dauert es knapp 10 das Script auszuführen (trotz schnellem Server). Zudem stimmen manche Zeilen nicht dh. es werden product_ids ausgelassen.
Habt ihr eine Lösugn für mich? Ein VIEW mit mysql? Eine direkte MYSQL Funktion? Oder eine Idee für ein PHP-Script?

Bin verzweifelt :(
 
Zuletzt bearbeitet:
Gibt es auch eine Tabelle mit den seriennummer? Also pro seriennummer eine eigene Zeile? Das würde es enorm vereinfachen.

Ansonsten kommst du fast nicht auf einen grünen Zweig
 
Nein gibt es nicht. Aber ich könnte eine Tabelle erstellen, in der für jede Seriennummer eine Zeile gibt.
Soll heißen ich ändere meine "Tabelle 2".
Schaut dann so aus:
id | product_id | seriennummer
1 | 123 | A
1 | 123 | B
1 | 200 | C
...


Würde das etwas bringen?
 
Oh ja! Normalisieren ist immer gut. Das vereinfacht das ganze immens

Etwa so könnte es dann gehen
SQL:
SELECT
    tbl_1.id,
    tbl_1.name,
    GROUP_CONCAT(DISTINCT tbl_2.seriennummer ORDER BY tbl_2.seriennummer DESC SEPARATOR ',') AS sn_list
FROM
    tbl_2,
    tbl_1
WHERE
    FIND_IN_SET(tbl_2.product_id, tbl_1.produkt_ids)
GROUP BY
    tbl_1.id,
    tbl_1.name

Merke dir. ID-Listen mit Kommas getrennt sind immer unpraktisch und unperformant. Wass man kann sollte man normalisieren. Sprich pro Nr eine Zeile. Dann kann SQL gut arbeiten.

Auch deine tabelle 1 sollte man normailsieren. Würde dir in Zukunft einige Probleme wegnehmen.
Also einfache eine Zuordnungstabelle machen wo pro tbl_1.id und passender produkt_id ein Eintrag drin ist.

siehe auch http://wiki.yaslaw.info/wikka/MySqlNormalizeFormSet
 
Zuletzt bearbeitet von einem Moderator:
Vielen Dank! Werde das ganze heute Nacht ausprobieren!!
Danke auch für deinen Link ...werde versuchen auch Tabelle 1 zu normalisieren.

Das Problem ist, das ich die Daten schon so bekomme, müsste also immer nachträglich normalisieren. Werde das ausprobieren.

Einstweilen vielen Dank :))
 
Hier noch ein kleines PHP-Script um die Seriennummern zu normalisieren. Natürlich ungetestet.

Annahnme: Die Zuordnungstabelle heisst sn_zuo und hat die Felder produkt_id und seriennummer
PHP:
$sql = 'SELCT produkt_id, seriennummer FROM tbl_2';
$result = mysql_query($sql);

$zuoInserts = array();

//Pro Eintrag...
while($row = mysql_fetch_assoc($result)){
    //und pro Serienennummer
    foreach(explode($row['seriennummer']) as $sn){
        //Die Value-Liste für einen INSERT zusammensetzen
        $insertValues = sprintf("(%d, '%s')", $row['produkt_id'], $sn);
        //Prüfen ob die Kombination schon vorhanden ist um Doppelte EInträge zu verhindern
        if(!in_array($insertValues, $zuoInserts)){
            //Wenn nicht, in den Array eintragen
            $zuoInserts[] = $insertValues;    
        }        
    }
}

//Alle Inserts des Array ausführen
$sql = "INSERT INTO sn_zuo (produkt_id, seriennummer) VALUES " . implode(',', zuoInserts);
mysql_query($sql);
 

Neue Beiträge

Zurück