Günsel: sum() aus left join Aufruf - Problem

Moin,

ich habe eine MySQL Left Join Abfrage von Tabelle rechung auf Tabelle postion.

Und in Tabelle Position gibt es zu jeder BESTELL_NR einen anderen PREIS.

Nun möchte ich die Summe von PREIS abfragen die der gleichen BESTELL_NR angehört.

Und so sieht meine stark vereinfachte Tabellenstruktur aus. Ich habe nicht die ganze Tabelle abgebildet, sondern nur ein Teil um es fürs Verständnis klar zu machen.

position

BESTELL_NR | PREIS | [...]
--------------------------
 1    | 1.19  | [...]

1         | 2.34  | [...]

1         | 6.47  | [...]

rechnung

BESTELL_NR | KD_NR  | [...]
--------------------------
 2    | 123    | [...]

3         | 184    | [...]

11        | 123    | [...]

Und so sieht meine MySQL Abfrage aus:

$result = mysql_query("SELECT kunde.KD_VORNAME, kunde.KD_NACHNAME , sum(position.PREIS)
          FROM
            rechnung
            LEFT JOIN kunde ON rechnung.KD_NR = kunde.KD_NR
            LEFT JOIN position ON rechnung.Bestell_NR = position.Bestell_NR
          GROUP BY position.PREIS
          WHERE
            BESTELL_NR  = '$bestell_nr'
          ORDER BY
            BESTELL_NR ASC
          ");

Jetzt ist mein Problem mir wird die Summe gar nicht ausgegeben, was ist daran falsch? Bzw. nach der Ergänzung mit der Preis-Abfrage wird mir gar nichts ausgegeben. Ich habe schon versucht meine Abfrage sum() anders zu schreiben aber alles fürht zu keinem Ergebnis.

Was habe ich falsch gemacht oder wie heißt es richtig?

Viele Grüße von Günsel

  1. Abgesehen davon muß es auch

    GROUP BY position.BESTELL_NR heissen aber gehen tut es trotzdem nicht !????

  2. yo,

    LEFT JOIN ist schon mal der falsche ansatz, es handelt sich um einen INNER JOIN. eine rechnung mit keiner position macht auf mich irgendwie keinen sinn. ich bin habe aber auch vom kaufmännischen her keine ahnung. ;-)

    der zweite punkt ist der, dass du Aggregtfunktionen und GROUP BY benutzt. auch wenn mysql keinen syntaktischen fehler ausgibt, sollte man immer die regel im auge behalten, dass du bei GROUP BY immer nur die spalten mit anzeigen läßt, nach denen du auch gruppiert hast oder eben aggregatfunktionen. deswegen muss man sich für die angaben der spalten, die nicht gruppiert wurde, etwas einfallen lassen.

    es geht mit unterabfragen, aber ich schlage dir einfach mal vor, es in zwei abfragen aufzuteilen, keep it simple. die entscheidene wäre dann....

    SELECT r.bestell_nr, sum(p.preis)
    FROM rechnung r, position p
    WHERE r.bestell_nr = p.bestell_nr
    AND r.bestell_nr  = 'wert'
    GROUP BY r.bestell_nr
    ORDER BY bestell_nr ASC;

    Ilja

    1. Moin

      LEFT JOIN ist schon mal der falsche ansatz, es handelt sich um einen INNER JOIN. eine rechnung mit keiner position macht auf mich irgendwie keinen sinn. ich bin habe aber auch vom kaufmännischen her keine ahnung. ;-)

      Auf dem ersten Blick gebe ich Dir recht, aber bei dieser Abfrage wird die postion nicht benötigt.

      Ich war gerade auch schon dabei ob mein left join falsch sei.
      Nur verstehe ich den Unterschied zwischen INNER und OUTER JOIN nicht ganz?

      der zweite punkt ist der, dass du Aggregtfunktionen und GROUP BY benutzt. auch wenn mysql keinen syntaktischen fehler ausgibt, sollte man immer die regel im auge behalten, dass du bei GROUP BY immer nur die spalten mit anzeigen läßt, nach denen du auch gruppiert hast oder eben aggregatfunktionen. deswegen muss man sich für die angaben der spalten, die nicht gruppiert wurde, etwas einfallen lassen.

      »»

      Es sollen bei mir die Preise gruppiert werden und daraus die Summe berechnet werden und die anderen Felder werde normal ausgegeben.
      Habe ich das in meinen Code nicht richtig geschrieben?

      es geht mit unterabfragen, aber ich schlage dir einfach mal vor, es in zwei abfragen aufzuteilen, keep it simple. die entscheidene wäre dann....

      »»

      was meinst du mit 2 Abfrage? 2 MySQL Abfragen über PHP ? Das wollte ich eigentlich vermeiden ich möchte es irgendwie in MySQL hinbekommen.

      SELECT r.bestell_nr, sum(p.preis)
      FROM rechnung r, position p
      WHERE r.bestell_nr = p.bestell_nr
      AND r.bestell_nr  = 'wert'
      GROUP BY r.bestell_nr
      ORDER BY bestell_nr ASC;

      So wie Du es gemacht hast funktioniert es auch nicht. Für mich ist es einfach zu verstehen ohne Alias zu arbeiten aber bei sum(PREIS) summe muss ein alias stehen sonst funktioniert es nicht. Das habe ich bereits herausgefunden. Und ORDER BY bestell_nr ASC brauche ich nicht weil es eh nur eine Ausgabe gibt, weil es auch nur eine Bestellnummer gibt.

      Außerdem macht Dein Code gar kein Sinn ich habe gar kein Bezug zu kunde und position. Da ist meine Lösung schon näher dran als Deine.

      Der Fehler wird im Join Verfahren stecken wo ich noch nicht weiß welcher der richtige ist, bzw ich versteh das nicht.

      position

      BESTELL_NR | PREIS | [...]
      --------------------------
       1         | 1.19  | [...]

      1         | 2.34  | [...]

      1         | 6.47  | [...]

      rechnung

      BESTELL_NR | KD_NR  | [...]
      --------------------------
       1         | 123    | [...]

      3         | 184    | [...]

      11        | 123    | [...]

      kunde

      KD_NR        | KD_ANREDE  | [...]
      ---------------------------------
       123         | Herr       | [...]

      184         | Frau       | [...]

      114         | Dr.        | [...]

      SELECT kunde.KD_ANREDE, kunde.KD_VORNAME, kunde.KD_NACHNAME , sum(PREIS) summe, rechnung.BESTELL_DATUM, rechnung.STATUS
                FROM
                  rechnung
                  LEFT JOIN kunde ON rechnung.KD_NR = kunde.KD_NR
                  LEFT JOIN position ON rechnung.Bestell_NR = position.Bestell_NR
                WHERE
                  BESTELL_NR  = '$bestell_nr'
                GROUP BY BESTELL_NR

      1. yo,

        Ich war gerade auch schon dabei ob mein left join falsch sei.
        Nur verstehe ich den Unterschied zwischen INNER und OUTER JOIN nicht ganz?

        nun, OUTER JOIN(LEFT oder RIGHT) nimmt alle einträge der einen tabelle und schaut, ob es passende einträge in der zweiten tabelle gibt. ist kein entspechender eintrag in der zweiten tabelle vorhanden, nimmt er die ergebnisse der ersten tabelle trotzdem. ein INNER JOIN nimmt nur dann die datensätze in den tabellen, wenn es immer auf beiden seiten einen oder mehrere datensätze entsprechend der join bedingung gibt.

        Es sollen bei mir die Preise gruppiert werden und daraus die Summe berechnet werden und die anderen Felder werde normal ausgegeben.

        wenn du nach den preisen gruppierst, dann bildet er die gruppe entsprechend gleicher preise, sprich alle datensätze mit gleichen preise, werden in eine gruppe abgelegt. vielleicht solltest du erst nochmal mit worten genau sagen, welches ergebnis du haben willst, damit ich besser nachvollziehen kann, was gesucht wird.

        was meinst du mit 2 Abfrage? 2 MySQL Abfragen über PHP ? Das wollte ich eigentlich vermeiden ich möchte es irgendwie in MySQL hinbekommen.

        machmal sind zwei mysql abfragen besser als eine komplizierte. erstens ist es in vielen fällen schneller und vor allem, es ist übersichtlicher. nicht alles, was man kann, sollte man auch tun.

        So wie Du es gemacht hast funktioniert es auch nicht. Für mich ist es einfach zu verstehen ohne Alias zu arbeiten aber bei sum(PREIS) summe muss ein alias stehen sonst funktioniert es nicht.

        es funktioniert auch ohne aliase, aber man kann doch jederzeit einen dazufügen: sum(preise) AS Summe

        Und ORDER BY bestell_nr ASC brauche ich nicht weil es eh nur eine Ausgabe gibt, weil es auch nur eine Bestellnummer gibt.

        das stimmt, hier ist die ORDER BY klausel überflüssig, da ja nur eine bestimmte bestellnummer ausgewählt wird.

        Außerdem macht Dein Code gar kein Sinn ich habe gar kein Bezug zu kunde und position.

        der bezug zu dem kunden wird in der angesprochenen zweiten abfrage deutlich, es ist die bestellnummer, über die der kunde ermittelt werden kann. da ich aber zwei abfragen für sinnvoller halte, habe ich die kundentabelle aber erst einmal weg gelassen. nicht desto trotz ist die beziehung aber durch die bestellnummer immer gegeben.

        Der Fehler wird im Join Verfahren stecken wo ich noch nicht weiß welcher der richtige ist, bzw ich versteh das nicht.

        möglich, aber das würde mich sehr wundern. wie gesagt. am besten noch mal in worten fassen, welches ergebnis du haben willst. bei mir dauert das manchmal, bis es kicl macht und ich weiss, was der andere will.

        Ilja

        1. nun, OUTER JOIN(LEFT oder RIGHT) nimmt alle einträge der einen tabelle und schaut, ob es passende einträge in der zweiten tabelle gibt. ist kein entspechender eintrag in der zweiten tabelle vorhanden, nimmt er die ergebnisse der ersten tabelle trotzdem. ein INNER JOIN nimmt nur dann die datensätze in den tabellen, wenn es immer auf beiden seiten einen oder mehrere datensätze entsprechend der join bedingung gibt.

          Der Fehler wird im Join Verfahren stecken wo ich noch nicht weiß welcher der richtige ist, bzw ich versteh das nicht.

          möglich, aber das würde mich sehr wundern. wie gesagt. am besten noch mal in worten fassen, welches ergebnis du haben willst. bei mir dauert das manchmal, bis es kicl macht und ich weiss, was der andere will.

          Hallo,

          also für mich stellt der INNER JOIN und der LEFT JOIN keine großen Unterschied da, weil in meinem Fall immer aus allen Tabellen mindestens ein Datensatz geholt wird.

          Ich habe mir gestern den ganzen Nachmittag den Kopf darüber zerbrochen wie eine Abfrage wohl aussehen könnte? Ich werde es wohl doch nun wie gewohnt über 2 SQL abfragen machen dazu habe ich ja bereits eine Lösung, ich hätte es nur schön gefunden wenn ich es auch mit einer gelöst hätte, dann hätte ich mal wieder was neues dazu gelernt und dazu gleich noch ein kleines Beispiel dazu gehabt.

          Aber ich versuche es nochmals in Worte zu fassen:

          Ich bekommen die BESTELL_NR in PHP über die Variabel $bestell_nr

          Ich benötige aus Tabelle rechung -> BESTELL_DATUM und STATUS
          (Beziehung über BESTELL_NR oder auch KD_NR)

          und aus Tabelle kunde -> KD_ANREDE, KD_VORNAME, KD_NACHNAME
          (Beziehung über KD_NR)

          und aus Tabelle position -> PREIS
          (Beziehung über BESTELL_NR)
          (Hier muss die gleiche BESTELL_NR gruppiert werden um die sum(PREIS) berechnen zu können)

          Vielleicht fällt einem dazu eine Lösung zu ein? Mir ist das persönlich etwas zu hoch :(

          Gruß Gunsel

          1. yo,

            versuch doch mal folgendes....

            SELECT r.bestell_nr, r.bestelldatum, r.status, k.kd_anrede, k.kd_vorname, k.kd_nachname, SUM(p.preis)
            FROM rechnung AS r, kunden AS k, position AS p
            WHERE k.kd_nr = r.kd_nr AND r.bestell_nr = p.bestell_nr
            AND r.bestell_nr = $bestell_nr
            GROUP BY r.bestell_nr, r.bestelldatum, r.status, k.kd_anrede, k.kd_vorname, k.kd_nachname;

            Ilja