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

Komplexes JOIN-Statement über 5 Tables (hierarchie)

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von MMachete, 19 Februar 2014.

  1. MMachete

    MMachete Neuer Benutzer

    Hallo liebe Datenbank-Spezialisten!
    Habe folgendes Problem bei einem Query in meiner Datenbank.
    Wie man im Bild erkennen kann, handelt es sich um eine Art "Quizz"-Applikation/Spiel.
    Es gibt 1-n Kategorien (zB 1), dazu 1-n Subkategorien (zB 1.1) und dafür wieder beliebig viele Sub-Subkategorien (zB 1.1.1) in welchen sich dann die Fragen befinden. Fragen können mit Werten von 1-5 bewertet werden.

    Mein Ziel ist es einen Query zu schreiben, der alle Ebenen1-Objekte anzeigt und ihren kumulierten Wert (SUM()) aller Fragen, die sich in dieser Kategorie (Ebene) befinden.
    Versucht habe ich das zuerst mit einem FULL JOIN. Result set zeigt: Nur die erste Kategorie und die Summe ALLER Fragen!

    Dann mit Subselect, Resultat: Es werden alle Ebene1-Objekte angezeigt und in der zweiten Column wieder der Gesamtwert ALLER Fragen.

    Wie kann ich in dem Query explizit zwischen Ebenen differenzieren?

    Bitte um Hilfe!! Queries kann ich gerne posten, sind halt ziemlich lange...


    MFG MM
     

    Anhänge:

  2. akretschmer

    akretschmer Datenbank-Guru

    Bilder sind Mist. Egal. Du scheinst sowas zu haben:

    Code:
    test=*# select * from c;
     id
    ----
      1
      2
    (2 rows)
    
    test=*# select * from c1;
     id | c
    ----+---
      1 | 1
      2 | 1
    (2 rows)
    
    test=*# select * from c2;
     id | c1
    ----+----
      1 |  1
      2 |  1
    (2 rows)
    
    test=*# select * from c3;
     id | c2
    ----+----
      1 |  1
      2 |  1
    (2 rows)
    
    test=*# select * from c4;
     id | c3 | wert
    ----+----+------
      1 |  1 |  10
      2 |  1 |  20
    (2 rows)
    
    und suchst:

    Code:
    test=*# select c.id, sum(c4.wert) from c left join c1 on c.id=c1.c left join c2 on c1.id=c2.c1 left join c3 on c2.id=c3.c2 left join c4 on c3.id=c4.c3 group by c.id;
    ;
     id | sum
    ----+-----
      1 |  30
      2 |
    (2 rows)
    
    Andreas
     
  3. MMachete

    MMachete Neuer Benutzer

    Hallo Andreas, danke für deine Antwort.
    Den von dir beschriebenen Query habe ich bereits so formuliert (nur ohne GROUP BY). Mit GROUP BY funktioniert es genausowenig!
    Bei mir sieht er folgendermaßen aus:
    Code:
    Select
      ebene1.e1bez,
      Sum(bewertung.wert) as punkte,
    From
      bewertung  Join
      erhebung On bewertung.eid = erhebung.eid  Join  
      frage On bewertung.frid = frage.frid  Join
      ebene3 On frage.e3id = ebene3.e3id  Join
      ebene2 On ebene3.e2id = ebene2.e2id  Join
      ebene1 On ebene2.e1id = ebene1.e1id
          
    Result-Set:
    Code:
    e1bez | punkte
    ------+--------
    1        | 7
    2        | 7
    
    Obwohl unterschiedliche Bewertungen (Werte) in den jeweiligen Fragen hinterlegt wurden, sind die Wertesummen in beiden Ebene1-Objekten gleich.
    Es wird alles summiert und auf die Hierarchie-Relation keine Rücksicht genommen.

    Mein Subquery:

    Code:
    Select
                      ebene1.e1id,
                        ( Select sum(b.wert)
                          from bewertung b
                              left join frage f on b.frid=f.frid
                              left join ebene3 e3 on f.e3id=e3.e3id
                              left join ebene2 e2 on e3.e2id=e2.e2id
                              left join ebene1 e1 on e2.e1id=e1.e1id
                          ) as punkte,
                      ebene1.e1bez,
                      ebene1.pkte
                  From
                      ebene1
                  where ebene1.e1bez=1 or 2
                  group by ebene1.e1id';
    Result-Set:
    Code:
    e1bez | punkte
    ------+--------
    1        | 14
    2        | 14
    
    Hier dasselbe Problem. Die beiden obersten Ebenen haben die gleichen Werte. Nur ist der Wert bei diesem Query doppelt so hoch.
    Wie muss ich den Query umformulieren, sodass zwischen Ebenen unterschieden wird und die Werte korrekt aufsummiert werden?

    MFG Max
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Was Du zeigst ist schon mal ein Syntaxfehler. Zumindest in allen 'richtigen' Datenbanken. Also alles != MySQL : in Abfragen mit einer Aggregation müssen alle Spalten des Resultates entweder in einer Aggregation oder im GROUP BY sein. MySQL schert sich hier (und anderswo) einen Scheiß um Normen und Syntax und korrekte Ergebnisse, und ich hab keinen weiteren Bock drauf, da noch viel Forschungsarbeit zu investieren, wie man an all den Fehlern von MySQL ohne blaue Augen vorbeimanövriert. Deal with it, or change it. In der Welt der freien Datenbanken ist alles besser als MySQL, angefangen von SQLlite bis PostgreSQL. Bei kommerziellen sowieso. Es gibt (für mich) keinen einzigen Grund, diesen Müll zu verwenden.
     
    Hony% gefällt das.
  5. MMachete

    MMachete Neuer Benutzer

    Sehr dankbar wäre ich für konstruktive und kompetente Beiträge, die sachlich auf die Problemstellung eingehen. MfG
     
  6. akretschmer

    akretschmer Datenbank-Guru

    Sorry, aber ich hab Dir eine Lösung gezeigt. Ich denke, diese funktioniert. Wenn das unter MySQL nicht geht, dann ist MySQL das falsche Werkzeug, in meiner Lösung ist exakt nix, was irgendwie rein nur unter PG funktioniert. Auch kenne ich Deine Ausgangsdaten nicht.
    Dein "funktioniert es genausowenig!" ist keine nachvollziehbare Beschreibung Deines Problems.
    Davon abgesehen, nochmals: ich denke, daß die von mir gezeigte Lösung korrekt ist und unter allen möglichen DB-Systemen funktioniert.

    Die Tatsache, daß, Zitat: "Den von dir beschriebenen Query habe ich bereits so formuliert (nur ohne GROUP BY)" unter MySQL ohne Syntaxfehler läuft ist kein tolles Feature von MySQL, sondern einfach nur FAIL. Dafür kannst Du nichts, ich weiß. Aber gestehe mir zu, daß ich einfach zum Ausdruck bringe, daß Du offenbar das falsche Werkzeug nutzt.
     
  7. Hony%

    Hony% Datenbank-Guru

    Ich muss da Andreas vollkommen Recht geben. Davon abgesehen das ebene1.e1bez auch unter MySQL ein Zufallswert. Bei einem Wechsel des Betriebssystems oder der MySQL Version kann sich das Ergebnis ändern.

    Wenn du auf kaputten Code bestehst kann dir Keiner zuverlässig helfen.
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Damit wir hier noch zu einem Ergebniss kommen:

    • erstelle vereinfachte Tabellen
    • fülle diese mit simplen Daten
    • fange mit 2 Tabellen an und baue Deine Abfrage auf
    • kontrolliere, ob das Ergebniss stimmt
    • gehe 2 Schritte zurück und nehme 1 Tabelle mehr in den JOIN
    • alle Tabellen im JOIN drin? Stimmt das Resultat?


    Behalte im Auge, daß MySQL sich nicht nach der SQL-Spezifikation richtet. Beachte die Regel, daß in Abfragen mit Aggregationen alle Spalten des Ergebnisses entweder aggregiert oder gruppiert sein müssen, auch wenn MySQL zu doof ist, das zu prüfen bzw. durchzusetzen. Schalte den Strict-Mode an ( http://dev.mysql.com/doc/refman/5.1/de/server-sql-mode.html ) oder, besser: nutze eine Datenbank, die sich normgerecht verhält und daher besser zum Lernen geeignet ist. Das kann z.B. SQLlite oder PostgreSQL sein.
     
    Hony% gefällt das.
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