Olli: MySQL-Abfrage

Abend,

ich versuche eine bestimmte Ergebnismenge durch eine MySQL-Abfrage zu erzielen, vielleicht kann mir einer weiterhelfen.

Das Ziel ist folgendes:

Tabelle 1: Vorträge
Tabelle 2: Referenten

Ergebnismenge: Alle Vorträge einmalig in der Liste, verknüpft mit einer beliebigen Anzahl Referenten.

In der Vortragstabelle steh im Feld Referenten z.B. "12;5;87"

Ich hätte gerne folgendes Ergebnis:
name=Vortrag X, Referenten=array(Max Muster, Josef Palaver)
oder
name=Vortrag X, Referenten=Max Muster;Josef Palaver

Mein bisheriger Ansatz:
SELECT p.*, CONCAT_WS(';','r.vorname','r.name') AS ref_name FROM #__aeb_program AS p LEFT JOIN #__aeb_referee AS r ON FIND_IN_SET( 'r.id', REPLACE( p.referee, ';', ',' ) ) > 0

Dadurch erhalte ich jedoch nur den ersten Referenten, nicht alle.

Danke für eure Mühe,

Olli

  1. Hi,

    In der Vortragstabelle steh im Feld Referenten z.B. "12;5;87"

    Warum ist das nicht vernünftig normalisiert?

    Mein bisheriger Ansatz:
    SELECT p.*, CONCAT_WS(';','r.vorname','r.name') AS ref_name FROM #__aeb_program AS p LEFT JOIN #__aeb_referee AS r ON FIND_IN_SET( 'r.id', REPLACE( p.referee, ';', ',' ) ) > 0

    Das soll MySQL-Code sein? Kann eigentlich nicht sein, das erste # würde einen Kommentar bis zum Rest der Zeile einleiten.

    Dadurch erhalte ich jedoch nur den ersten Referenten, nicht alle.

    Du suchst ja auch in der Spalte p.referee nach dem Text 'r.id', der dort nach deinen Angaben aber gar nicht drinsteht.

    In einem vernünftigen Datenmodell wäre das gewünschte Ergebnis mittels GROUP_CONCAT relativ leicht zu erreichen;
    bei dem vorliegenden vermurksten Datenmodell sehe ich da aber auf Anhieb überhaupt keine „Lösung“ rein in SQL, die ohne sehr eklige Basteleien auskommen würde.

    MfG ChrisB

    --
    RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
    1. Hallo,

      danke für eure Hilfe.

      Warum ist das nicht vernünftig normalisiert?

      Ich bin weder Datenbank- noch MySQL-Profi, aber ich dachte die beiden Tabellen seien sinnvoll normalisiert. Wenn dem nicht so ist, wäre ich sehr daran interessiert, wie dieses Datenmodell denn vernünftig aussehen würde!

      Verzeiht die fehlende Erklärung zum MySQL-Code. Dieser stammt aus einer Joomla-Komponente. In Joomla werden Tabellen über #__ angesprochen, was Joomla dann durch einen Prefix ersetzt.

      Danke und Gruß,
      Olli

      1. Hi,

        Warum ist das nicht vernünftig normalisiert?

        Ich bin weder Datenbank- noch MySQL-Profi, aber ich dachte die beiden Tabellen seien sinnvoll normalisiert.

        Nein, wenn sowas

        In der Vortragstabelle steh im Feld Referenten z.B. "12;5;87"

        der Fall ist, kann davon nicht die Rede sein.

        Das verletzt schon die erste Normalform (1NF), die fordert: „Jedes Attribut der Relation muss einen atomaren Wertebereich haben.“

        Üblich ist es, bei der Datenmodellierung bis zur 3NF zu gehen; Abweichungen davon sind natürlich möglich, wenn es gute Gründe dafür gibt.

        Wenn dem nicht so ist, wäre ich sehr daran interessiert, wie dieses Datenmodell denn vernünftig aussehen würde!

        Die Zuordnung Vortrag:Referent sollte in eine eigene Tabelle ausgelagert sein.

        MfG ChrisB

        --
        RGB is totally confusing - I mean, at least #C0FFEE should be brown, right?
  2. Hallo Olli,

    Das Ziel ist folgendes:

    Tabelle 1: Vorträge

    warum nennst Du diese mit dem zwingend zu quotenden Namen

    #__aeb_program

    Tabelle 2: Referenten

    für diese gilt das gleiche.

    #__aeb_referee

    Ergebnismenge: Alle Vorträge einmalig in der Liste, verknüpft mit einer beliebigen Anzahl Referenten.

    In der Vortragstabelle steh im Feld Referenten z.B. "12;5;87"

    wie Dir schon gesagt wurde, ist das eine denkbar schlechte Idee. Diesen schlimmen Fehler solltest Du unbedingt beheben. Er führt zuerst zu schrecklichen SQL-Verrenkungen und dann zu noch schrecklicher Performance.

    SELECT p.*, CONCAT_WS(';','r.vorname','r.name') AS ref_name FROM #__aeb_program AS p LEFT JOIN #__aeb_referee AS r ON FIND_IN_SET( 'r.id', REPLACE( p.referee, ';', ',' ) ) > 0

    Dadurch erhalte ich jedoch nur den ersten Referenten, nicht alle.

    Dadurch erhalte ich niemals den ersten Referenten. Ein paar Fehler hat Chris bereits aufgezeigt. Ich sehe weder eine Gruppierung noch eine Aggregatsfunktion, die Einträge einer Gruppe zusammenfassen soll.

    Wie könntest Du an Deine Referentenliste kommen?
    Im ersten Schritt ermittelst Du alle Referenten-IDs. Dazu kannst Du die Geschichte mit FIND_IN_SET und REPLACE verwenden :-(

    Ich habe noch ein paar fehlerhaft eingesetzte einfache Anführungszeichen entfernt. Wenn Du fragst, was da fehlerhaft war, dann lege ich Dir den Handbuchabschnitt "Schema Object Names" ans Herz:

    SELECT  
        p.name,  
        CONCAT_WS(', ', r.vorname, r.name) ref_name  
    FROM  
        `#__aeb_program` p  
    LEFT JOIN  
        `#__aeb_referee` r  
    ON  
        FIND_IN_SET(r.id, REPLACE( p.referee, ';', ',' ))
    

    liefert Dir eine Liste der (hoffentlich eindeutigen) Vortragsnamen und der zugehörigen Referenten. Im nächsten Schritt gruppierst Du nach dem Vortragsnamen (besser nach dem Primärschlüssel der Vortragstabelle) und wendest auf die Referenten die Aggregatsfunktion GROUP_CONCAT mit dem von Dir gewünschten Trennzeichen an.

    Ach ja: schön ist das nicht. Bitte korrigiere das kaputte Tabellendesign.

    Freundliche Grüße

    Vinzenz