Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Join - Howto

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von mobilo, 27 November 2014.

  1. mobilo

    mobilo Neuer Benutzer

    Guten Morgen,

    ich weiss nicht, wie ich folgendes Problem lösen kann:

    Es gibt eine Tabelle
    egw_addressbook (contact_id, name, org_name, contact_email, ...)
    in der die wesentlichen Kontaktdaten gespeichert werden und es gibt eine weitere Tabelle
    egw_addressbook_extra (contact_id, contact_name, contact_value)
    in der benutzerdefinierte Zusatzdaten gespeichert werden.

    In der egw_addressbook_extra steht z.b. sowas:

    4711, Skonto, 3
    4711, Freigrenze, 500
    4711, Bild, abc.gif
    4821, Skonto,4
    4821, Familienstand, ledig
    4813, Skonto,4
    4813, Bild, blue.gif
    4813, Geschlecht, männlich

    Verknüpfen kann man die über
    ON egw_addressbook.contact_id=egw_addressbook_extra.contact_id

    Jetzt möchte ich gerne eine Abfrage haben, die mir sämtliche Kontaktdaten aus der ersten Tabelle und zusätzlich alle Extra-Daten aus letzterer Tabelle liefert.

    z.B. sollte sowas rauskommen:


    4711, Meier, BMW, meier@bmw.de, Skonto=3, Freigrenze=500, Bild=abc.gif
    4821, Stein, BASF, stein@basf.de, Skonto=4, Familienstand=ledig
    4813, Koch, Audi, koch@audi.de, Skonto=4, Bild=blue.gif, Geschlecht=männlich



    Ich hab's mal so probiert:
    SELECT distinct egw_addressbook.contact_id, egw_addressbook.org_name, egw_addressbook.contact_email, egw_addressbook_extra.contact_name, egw_addressbook_extra.contact_value

    as lieferanteninfosFROM egw_addressbook
    JOIN egw_addressbook_extraegw_addressbook_extra ON egw_addressbook.contact_id = egw_addressbook_extra.contact_id

    Where egw_addressbook.contact_id=339
    ORDERBY egw_addressbook.contact_id ASC

    aber da bekomme ich 8 rows zurückgeliefert, weil es 8 Einträge in der egw_addressbook_extra gibt...
    Kann man sowas mit SQL überhaupt lösen?
     
    Zuletzt bearbeitet: 27 November 2014
  2. akretschmer

    akretschmer Datenbank-Guru

    Natürlich. Du mußt das aggreieren. In PostgreSQL geht es so:

    Code:
    test=# create table egw(id int primary key, name text);
    CREATE TABLE
    Time: 45,552 ms
    test=*# create table egw_extra(id int references egw, key text, value text);
    CREATE TABLE
    Time: 83,234 ms
    test=*# insert into egw values (1, 'name1');
    INSERT 0 1
    Time: 1,962 ms
    test=*# insert into egw_extra values (1, 'extra 1', 'value extra 1');
    INSERT 0 1
    Time: 0,847 ms
    test=*# insert into egw_extra values (1, 'extra 2', 'value extra 2');
    INSERT 0 1
    Time: 0,330 ms
    test=*# insert into egw_extra values (1, 'extra 3', 'value extra 3');
    INSERT 0 1
    Time: 0,332 ms
    test=*# commit;
    COMMIT
    Time: 0,529 ms
    test=*# select egw.id, egw.name, array_to_string(array_agg(egw_extra.key || ':' || egw_extra.value),', ') from egw left joinegw_extra on egw.id=egw_extra.id group by egw.id, egw.name;
     id | name  |  array_to_string
    ----+-------+---------------------------------------------------------------------
      1 | name1 | extra 1:value extra 1, extra 2:value extra 2, extra 3:value extra 3
    (1 row)
    
    Time: 1,165 ms
    
    MySQL kennt kein array_agg, aber irgendwie ein group_concat oder sowas.
     
    ukulele gefällt das.
  3. mobilo

    mobilo Neuer Benutzer

    Ich bekomme das nicht hin... MySQL kennt auch kein array_to_string lt. Fehlermeldung..

    Gibt's hier jemanden, der das für mich mal in MySQL übersetzen könnte?
     
  4. akretschmer

    akretschmer Datenbank-Guru

    ja, laß es einfach weg. In PostgreSQL macht das array_agg() ein Array:

    Code:
    test=*# select egw.id, egw.name, array_agg(egw_extra.key || ':' || egw_extra.value) from egw left join egw_extra on egw.id=egw_extra.id group by egw.id, egw.name;
     id | name  |  array_agg
    ----+-------+---------------------------------------------------------------------------
      1 | name1 | {"extra 1:value extra 1","extra 2:value extra 2","extra 3:value extra 3"}
    (1 row)
    
    Das array_to_string() dient nur der Aufhübschung ;-)
     
  5. mobilo

    mobilo Neuer Benutzer

    So ich hab's jetzt anders hinbekommen. Danke trotzdem für das schubsen in die richtige Richtung.

    Hier meine Lösung:

    SELECT a.contact_id, a.org_name, count(DISTINCT e.contact_name) as anzahl,
    CONVERT (GROUP_CONCAT (e.contact_name, '=' , e.contact_value) USING utf8 ) AS zusatzinfos
    from egw_addressbook_extra as e
    left join egw_addressbook as a on a.contact_id=e.contact_id
    Where a.contact_id=339
    group by e.contact_id order by anzahl ASC
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Die wird in zukünftigen Versionen von MySQL einen Systaxfehler erzeugen und nicht mehr funktionieren. In Abfragen mit Aggregationen müssen alle Spalten des Resultates entweder aggregiert oder gruppiert werden - das ist bei Dir nicht der Fall. Derzeit ist MySQL auf dem Auge noch blind und erkennt den Fehler nicht, aber 5.7.5 erkennt ihn bereist - so wie alle anderen Datenbanken der Welt das schon immer erkennen. Bis dahin liefert MySQL ein zufälliges Resultat aus. Kann also sein, daß es zufällig richtig ist, bei Mondschein und Ebbe aber halt auch falsch sein kann.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden