Ausgabe der CSV, mehrere Werte pro Spalte in einer Zeile kombinieren

ikodi

Benutzer
Beiträge
7
Hallo liebe Community,

ich bin sehr neu in dem Bereich und brauche etwas Hilfe bei einer Abfrage.

Es ist ein Onlineshop und ich möchte gerne eine Tabelle erstellen,
die ausgibt, welche Kunden einen bestimmten Artikel gekauft haben.

Die Artikel haben teils mehrere Varianten. Max. 3.

In dem Beispiel sind es nur 2.
Größe und Farbe
Und ich möchte den Artikel RV MANUELA abfragen.

Wenn ich nun die Abfrage mache,
erstellt es mir immer eine neue Zeile für dieselbe Bestellung, da der Artikel aus zwei Varianten besteht.
Ich würde gerne diese beiden Werte in einer Zeile und einer Zelle hintereinander stehen haben.

Als Beispiel in der ersten Zeile könnte auch T und U zusammengefasst werden:
Als Beispiel wie im Bild : "Größen: 98 - 104 (0), Farbe: kingfisher" oder ähnlich.
Ich habe das mal exemplarisch manuell in der Excel angepasst.
Normal steht in der Tabelle an T2 nur Größen.

Bildschirmfoto 2024-09-14 um 21.48.46.webp

Die zwei Werte für die Variante werden hier gezogen:

orders_products_properties.properties_name,
orders_products_properties.values_name,

Auf dem angehängten Bild sieht man, wie immer zwei Zeilen erzeugt werden.

Für jegliche Hilfe bin ich sehr dankbar.

Beste Grüße,
Marko


MySQL-Version: 10.11.4-MariaDB-1--10.11.4+maria~deb11-log
PHP Version 8.2.23


Dies wäre mein Script:

PHP:
<?php
    // Verbindung zur Datenbank herstellen
    $host = "localhost";
    $user = "geheim";
    $password = "geheim";
    $dbname = "geheim";

   $conn = mysqli_connect($host, $user, $password, $dbname);

    // Abfrage vorbereiten und ausführen
    $query = "SELECT
                orders.orders_id,
                orders.date_purchased,
                orders.customers_name,
                orders.customers_company,
                orders.customers_firstname,
                orders.customers_lastname,
                orders.customers_telephone,
                orders.customers_city,
                orders.customers_postcode,
                orders.customers_email_address,
                orders.delivery_name,
                orders.delivery_street_address,
                orders.delivery_city,
                orders.payment_method,
                orders.gambio_hub_module_title,
                orders_products.final_price,
                orders_products.products_quantity,
                products.products_model,
                orders_products.products_name,
                orders_products_properties.properties_name,
                orders_products_properties.values_name,
                products.products_ordered
               

                FROM
                    orders
                    JOIN orders_products ON orders_products.orders_id = orders.orders_id
                    JOIN products ON orders_products.products_id = products.products_id
                    JOIN orders_products_properties ON orders_products.orders_products_id = orders_products_properties.orders_products_id
                   
                               
                WHERE
                    orders_products.products_model = 'RV MANUELA--'";
                   
                               
 $result = mysqli_query($conn, $query);

    // CSV-Datei erstellen und Daten schreiben
    $file = fopen('abfragen_artikel.csv', 'w');

    //Spaltennamen
    $column_names = array("Bestellnummer",
                            "Bestelldatum",
                            "Name",
                            "Company",
                            "Vorname",
                            "Nachname",
                            "Telefonnummer",
                            "Stadt",
                            "Postleitzahl",
                            "Email Adresse",
                            "Versand Name",
                            "Versand Strasse",
                            "Versand Stadt",
                            "Bezahlmethode",
                            "Bezahlmethode02",
                            "Endpreis Kunde",
                            "Anzahl",
                            "Produkt ID",
                            "Produktname",
                            "Varianten Name",
                            "Variante",
                            "Gesamtanzahl Verkäufe");
                           
    fputcsv($file, $column_names, '|');
   
    while ($row = mysqli_fetch_assoc($result)) {
        fputcsv($file, $row, '|');
    }

    fclose($file);
    mysqli_close($conn);

    // Erfolgsmeldung ausgeben
    echo "Der Export wurde erfolgreich abgeschlossen!";
?>
 
Zuletzt bearbeitet:
Werbung:
Ich würde gerne diese beiden Werte in einer Zeile und einer Zelle hintereinander stehen haben.
Du kannst group_concat() einsetzen.

Du müsstest überlegen, ob das allgemein funktioniert, beliebige Properties ungefiltert zu übernehmen.
Nach meinem Verständnis würde ja eine Bestellung ein konkrete Variante festlegen. Folglich muss es dazu irgendwo Informationen geben, mit denen man auf einen Wert in Properties filtern kann.
Gibt es besonders viele Properties, ist das Group_concat Verfahren vielleicht nicht sehr gut geeignet, weil es viele Daten liefert, die vielleicht gar nicht von Bedeutung sind.
 
Also zunächst musst du dir überhaupt einmal GROUP BY anschauen. Du hast eine Liste von Einzeldatensätzen und willst diese gruppieren, vermutlich auch aggregieren. Wenn dann Textinformationen aggregiert werden sollen, dann kommt, group_concat() ins Spiel.
 
Hallo und vielen Dank. 😀
Das hat in Kombi mit den beiden Befehlen super geklappt. Genau wie ich es haben wollte.
Noch mal vielen lieben Dank! 🙏

Rein informativ hier das Ergebnis, wie ich es gelöst habe und das Ergebnis im Screenshot.

Liebe Grüße, Marko

PHP:
    // Abfrage vorbereiten und ausführen
    $query = "SELECT
                orders.orders_id,
                orders.date_purchased,
                orders.customers_name,
                orders.customers_company,
                orders.customers_firstname,
                orders.customers_lastname,
                orders.customers_telephone,
                orders.customers_city,
                orders.customers_postcode,
                orders.customers_email_address,
                orders.delivery_name,
                orders.delivery_street_address,
                orders.delivery_city,
                orders.payment_method,
                orders.gambio_hub_module_title,
                orders_products.final_price,
                products.products_model,
                orders_products.products_name,
                orders_products.products_quantity,
                group_concat(orders_products_properties.properties_name SEPARATOR ' * '),
                group_concat(orders_products_properties.values_name SEPARATOR ' * '),
                products.products_ordered
                

                FROM
                    orders
                    JOIN orders_products ON orders_products.orders_id = orders.orders_id
                    JOIN products ON orders_products.products_id = products.products_id
                    JOIN orders_products_properties ON orders_products.orders_products_id = orders_products_properties.orders_products_id
                    
                                
                    WHERE
                        orders_products.products_model = 'RV MANUELA--'
                        
                        Group BY
                            orders.orders_id";
                        
                                                                    
                                
 $result = mysqli_query($conn, $query);

    // CSV-Datei erstellen und Daten schreiben
    $file = fopen('abfragen_artikel.csv', 'w');

    //Spaltennamen

Bildschirmfoto 2024-09-16 um 14.20.41.webp
 
BTW Ich finde leider keinen Button für "gelöst" oder dergleichen.
Vielleicht kann mir da jemand einen Tipp geben.
Oder dies auslösen?
Vielen Dank!
 
Button für gelöst gibt es leider nicht.

Dein SQL ist allerdings syntaktisch falsch. Das dürfte in einer aktuellen MySQL Version so eigentlich nicht laufen, in jeder vernünftigen Datenbank schonmal gar nicht. Daher ist das Ergebnis theoretisch Zufall und daher unzuverlässig - eine Unsitte seitens MySQL das so auszuführen.

Bei Verwendung von GROUP BY muss jede Spalte entweder gruppiert werden (im GROUP BY aufgeführt werden) oder aggregiert werden (per Funktion im Select-Teil). Du solltest das ergänzen, damit es nicht irgendwann plötzlich nicht mehr läuft.
 
Button für gelöst gibt es leider nicht.

Dein SQL ist allerdings syntaktisch falsch. Das dürfte in einer aktuellen MySQL Version so eigentlich nicht laufen, in jeder vernünftigen Datenbank schonmal gar nicht. Daher ist das Ergebnis theoretisch Zufall und daher unzuverlässig - eine Unsitte seitens MySQL das so auszuführen.

Bei Verwendung von GROUP BY muss jede Spalte entweder gruppiert werden (im GROUP BY aufgeführt werden) oder aggregiert werden (per Funktion im Select-Teil). Du solltest das ergänzen, damit es nicht irgendwann plötzlich nicht mehr läuft.

Okay, ich danke dir.
Aktuell funktioniert es wohl und reicht für meine Zweck vollkommen aus.
Aber danke für den Tipp.
Dann weiß ich woran es liegt, sollte da mal was komisches rauskommen. 👍
 
Aktuell funktioniert es wohl und reicht für meine Zweck vollkommen aus
Wie hast Du das geprüft?

Es "funktioniert", weil ein Ergebnis kommt, dass dem Augenschein nach "ganz plausibel" aussieht?
Wieviel Datensätze sind betroffen? Wieviel davon hast Du Dir angesehen und das Ergebnis Buchstabe für Buchstabe geprüft?

Dieses "Verhalten" von mysql / maria ist kein Spaß. Es ist genau genommen zum Kotzen. Du willst dich niemals(!) darauf verlassen, dass die DB Engine Deine Abfrage interpretiert und Dir die Arbeit abnimmt, eine Handvoll Feldnamen in Dein SQL Statement aufzunehmen.
Sobald die Basisdaten Deines Statements sagen wir die Zahl von 100 überschreitet, ist eine manuelle Kontrolle aussichtslos. Und es wäre selbst bei buchstäblicher Kontrolle müßig, weil Du keine Garantie hast, dass das nächste Select das gleiche, richtige Ergebnis liefert.

Es gibt Schalter, mit denen Du diese "tolle Komfortfunktion" abschalten kannst. Mach das und Dein Statement wird nicht mehr laufen, sondern statt dessen einen Fehler werfen. Das ist das einzige worauf Du dich verlassen kannst und solltest.
 
Danke für deine Antwort.
Es geht lediglich um eine informative Abfrage für uns in der Firma.
Es werden keine Daten daraus verwendet und wieder irgendwo reingeschrieben.
Wenn nötig, werden die Ergebnisse daraus noch mal im Shop gegengeprüft.

Die Anzahl der Verkäufe von diesem Artikel sind gesamt 110.
In der erzeugten Tabelle sind genau diese 110 vorhanden.
Alle Angaben zu den Bestellungen finden sich in der Tabelle identisch wieder, wie sie der Realität entsprechen.
Mit einer anderen Suchanfrage konnte ich das Ergebnis erfolgreich reproduzieren.

Ich muss aktuell kein absoluter Experte in diesem Bereich werden und bin sehr froh, dass mir hier so schnell für mein Problem geholfen werden konnte.
Mit dem Ergebnis bin ich sehr zufrieden.

Du hattest kurz die Anzahl der Datensätze angesprochen.
Es sind 350 Tabellen und ca. 650.000 Einträge sprich Zeilen.
Ich weiß nicht ob das groß, klein oder üblich ist.
Wie gesagt funktioniert in dieser Dimension alles gut.

Danke dir aber für deinen Hinweis und muss mich dann ggf. noch mal mehr mit beschäftigen, sollte es nicht mehr funktionieren.

Liebe Grüße, Marko
 
Ich muss aktuell kein absoluter Experte in diesem Bereich werden
Gut, aber darum geht es gar nicht. Bei dem Problem geht es um ein Standardverfahren. Es gibt nur ein einziges Datenbanksystem, dass diesen Fehler macht und Du nutzt es.
Es gibt einfach 2 Möglichkeiten. Du machst einmalig oder immer wieder Prüfungen, ebenso Deine Kollegen und ihr seid trotzdem nie sicher, ob die Daten beim nächsten Mal stimmen. Oder
Also zunächst musst du dir überhaupt einmal GROUP BY anschauen
und verstehen. Dann muss sich zukünftig niemand mehr den Kopf zerbrechen oder mit unsicheren Infos arbeiten.

Es ist arbeitsintensiv, aussichtslos und sinnlos, Stichproben jenseits von 100 Datensätzen zu kontrollieren. Das muss und kann die DB perfekt (außer sie wird falsch benutzt).
Zum Vergleich: Wenn Du verstanden hast, wie das Statement richtig lautet- und das ist das einzige, was fehlt- dann stellst Du fest, dass Du lediglich Deine übrigen Felder in die Group by Clause eintragen musst, dann ist alles gut:
Code:
orders.date_purchased, orders.customers_name, orders.customers_company,
orders.customers_firstname, orders.customers_lastname, orders.customers_telephone,
orders.customers_city, orders.customers_postcode, orders.customers_email_address, orders.delivery_name,
orders.delivery_street_address, orders.delivery_city, orders.payment_method,
orders.gambio_hub_module_title, orders_products.final_price,
products.products_model, orders_products.products_name, orders_products.products_quantity,
products.products_ordered
 
Ich sehe das nicht ganz so dramatisch aber du tust dir keinen Gefallen wenn du das potenzielle Problem einfach akzeptierst, der Aufwand für die Lösung ist minimal. Einfach alle Spalten, die nicht in group_concat stehen, ins GROUP BY aufnehmen.
 
Hallo und vielen Dank für eure Hinweise.
Ich möchte ja nicht als unbelehrbar erscheinen und habe es nun, wie Ukulele beschrieben hat, geändert. :)
Ich sehe das nicht ganz so dramatisch aber du tust dir keinen Gefallen wenn du das potenzielle Problem einfach akzeptierst, der Aufwand für die Lösung ist minimal. Einfach alle Spalten, die nicht in group_concat stehen, ins GROUP BY aufnehmen.
Das Ergebnis in der Tabelle ist tatsächlich exakt das selbe.
Und ich hoffe es ist in Zukunft resistent gegen mögliche Fehler, wie ihr ausgeführt habt.
Den Code habe ich wie folgt geändert:

PHP:
<?php
    // Verbindung zur Datenbank herstellen_Sensible Daten entfernt
   

   $conn = mysqli_connect($host, $user, $password, $dbname);

    // Abfrage vorbereiten und ausführen
    $query = "SELECT
                orders.orders_id,
                orders.date_purchased,
                orders.customers_name,
                orders.customers_company,
                orders.customers_firstname,
                orders.customers_lastname,
                orders.customers_telephone,
                orders.customers_city,
                orders.customers_postcode,
                orders.customers_email_address,
                orders.delivery_name,
                orders.delivery_street_address,
                orders.delivery_city,
                orders.payment_method,
                orders.gambio_hub_module_title,
                orders_products.final_price,
                products.products_model,
                orders_products.products_name,
                orders_products.products_quantity,
                group_concat(orders_products_properties.properties_name SEPARATOR ' * '),
                group_concat(orders_products_properties.values_name SEPARATOR ' * '),
                products.products_ordered
               

                FROM
                    orders
                    JOIN orders_products ON orders_products.orders_id = orders.orders_id
                    JOIN products ON orders_products.products_id = products.products_id
                    JOIN orders_products_properties ON orders_products.orders_products_id = orders_products_properties.orders_products_id
                   
                               
                    WHERE
                        orders_products.products_model = 'RV MANUELA--'
                       
                        Group BY
                            orders.orders_id,
                            orders.date_purchased,
                            orders.customers_name,
                            orders.customers_company,
                            orders.customers_firstname,
                            orders.customers_lastname,
                            orders.customers_telephone,
                            orders.customers_city,
                            orders.customers_postcode,
                            orders.customers_email_address,
                            orders.delivery_name,
                            orders.delivery_street_address,
                            orders.delivery_city,
                            orders.payment_method,
                            orders.gambio_hub_module_title,
                            orders_products.final_price,
                            products.products_model,
                            orders_products.products_name,
                            orders_products.products_quantity,
                            products.products_ordered";
                       
                                                                   
                               
 $result = mysqli_query($conn, $query);

    // CSV-Datei erstellen und Daten schreiben
    $file = fopen('abfragen_artikel.csv', 'w');

    //Spaltennamen
    $column_names = array("Bestellnummer",
                            "Bestelldatum",
                            "Name",
                            "Company",
                            "Vorname",
                            "Nachname",
                            "Telefonnummer",
                            "Stadt",
                            "Postleitzahl",
                            "Email Adresse",
                            "Versand Name",
                            "Versand Strasse",
                            "Versand Stadt",
                            "Bezahlmethode",
                            "Bezahlmethode02",
                            "Endpreis Kunde",
                            "Produkt ID",
                            "Produktname",
                            "Anzahl gleicher Artikel",
                            "Varianten Name",
                            "Varianten",
                            "Gesamtanzahl Verkäufe");
                           
    fputcsv($file, $column_names, '|');
   
    while ($row = mysqli_fetch_assoc($result)) {
        fputcsv($file, $row, '|');
    }

    fclose($file);
    mysqli_close($conn);

    // Erfolgsmeldung ausgeben
    echo "Der Export wurde erfolgreich abgeschlossen!";
?>

Vielen Dank noch mal!!!

Liebe Grüße, Marko
 
Werbung:
Ach so. Und den LIKE Operator habe ich auch kennengelernt. :)

WHERE
orders_products.products_model LIKE '%Manuela%'

Klappt super mit allen Artikeln.
 
Zurück
Oben