mixmastertobsi: Datenbankabfrage

Hallo, ich versuche mich an folgender Abfrage.
Leider bekomme ich immer eine Fehlermeldung. (Invalid use of group function)

Wie kann ich eine Summe in der MysqlAbfrage bilden und diese mit dem gesamtbetrag vergleichen?

SELECT auftrag.date,auftrag.auftragnr,auftrag.status, auftrag.pausevon, auftrag.pausebis FROM auftrag LEFT JOIN shop_zahlungsarten ON auftrag.payment=shop_zahlungsarten.id LEFT JOIN auftrag_zahlung ON auftrag_zahlung.auftragnr=auftrag.auftragnr WHERE shop_zahlungsarten.pay='1' AND auftrag.gesamtpreis<=SUM(auftrag_zahlung.betrag) AND auftrag.status='2' OR shop_zahlungsarten.pay!='1' AND auftrag.status='2' order by auftrag.date

  1. Hi!

    Wie kann ich eine Summe in der MysqlAbfrage bilden und diese mit dem gesamtbetrag vergleichen?

    Ermittle die Summe in einer Subquery.

    Lo!

  2. moin,

    ich habe mal deine abfrage ein klein wenig formatiert, was man übrigens immer machen sollte. mal von der summe und dein problem abgesehen, hast du ein paar logische fehler in deiner abfrage.

    SELECT a.date, a.auftragnr,a.status, a.pausevon, a.pausebis
    FROM auftrag a
    LEFT JOIN shop_zahlungsarten sz ON a.payment = sz.id
    LEFT JOIN auftrag_zahlung az ON az.auftragnr = a.auftragnr
    WHERE sz.pay = '1'
    AND a.gesamtpreis <= SUM(az.betrag)
    AND a.status = '2'
    OR sz.pay != '1' AND a.status='2'
    ORDER BY a.date
    ;

    1. du machst jeweils einen LEFT JOIN auf zwei tabellen, die du noch in der WHERE klausel bei bedinungen mit einbaust. das macht keinen sinn und ist ein logischer fehler. stell dir vor, der OUTER JOIN hat einen datensatz auftrag, der keinen entsprechenden datensatz in der shop_zahlungsart tabelle hat. dann würde man denken, der auftrag würde trotzdem angezeigt werden, da es sich ja um einen OUTER JOIN auf die tabelle auftrag_zahlung handelt. alle werte der auftrag_zahlungs tabelle würden dann mit NULL werten aufgefüllt werden. und wenn du für die spalte sz.pay den wert NULL hast und mit '1' vergleicht, dann schließt er den datensatz wieder aus. sprich, du hast nur einen gefühlten OUTER JOIN, faktisch machst du einen INNER JOIN.

    2. du willst den gesamtpreis aus tabelle auftrag vermutlich nicht mit der gesamten summe aus der tabelle auftrag_zahlung vergleichen, sondern eben nur mit mit der summe, die die gleiche auftragsnummer haben wie der auftrag.

    3. es macht heute keinen sinn mehr, in statuswerte so was wie 01, 02, 03, oder 1,2,3 stehen zu haben. das hat man früher sehr oft gemacht, vermutlich um speicherplatz zu sparen. heute solltest du dafür immer sprechende werte nehmen wie zum beispiel NEU, AKTIV, BEENDET.

    4. mir ist dieser teil noch unklar: a.gesamtpreis <= SUM(az.betrag) willst du wirklich die werte haben die kleiner sind und die gleich sind oder nur die kleiner sind ?

    5. Joins sind oftmals problematisch, man muss sich sehr genau anschauen, was man dabei macht. oftmals verändert sich die anzahl der datensätze ungewollt in der ergebnismenge durch Joins. man muss sich dabei immer genau überlegen, was man tut.

    um das zu machen, was du suchst sind wohl korrelierte unterabfragen am besten, was deldfix bereits erwähnte. aber ich würde gerne vorher erst mal wissen, was genau du machen willst, also in worten was für ein ergebnis erwartest du. am besten mit beispiel.

    Ilja

    1. Hallo,

      es gibt Aufträge, die per Vorkasse bezahlt werden und welche, die per Nachnahme versand werden. Daher dieses OR in der WHERE Klausel.

      sz.pay = '1'
      AND a.gesamtpreis <= SUM(az.betrag)
      AND a.status = '2'

      Übersetzt
      Zeige Datensätze, welche

      per Vorkasse bezahlt werden müssen
      der bezahlte Betrag größer ode gleich ist wie "gesamtpreis"
      Auftragstatus 2 ist

      ODER

      per Vorkasse NICHT bezahlt werden müssen
      Auftragstatus 2 ist

      1. moin,

        für die zwei fälle hast du mehrere möglichkeiten, zum einen sicherlich mit einem OR operator, zum anderen könnte man auch UNION ALL einsetzen. leider hast du keine beispieldaen genannt, das macht es immer ein wenig schwieriger. aber ich vermute du willst so was:

        SELECT a.date, a.auftragnr,a.status, a.pausevon, a.pausebis
        FROM auftrag a
        INNER JOIN shop_zahlungsarten sz ON sz.id = a.payment
        WHERE a.status = '2'
        AND sz.pay = '1'
        AND a.gesamtpreis <= (SELECT SUM(az.betrag)
                              FROM auftrag_zahlung az
                              WHERE az.auftragnr = a.auftragnr
                             )
        UNION ALL
        SELECT a2.date, a2.auftragnr,a2.status, a2.pausevon, a2.pausebis
        FROM auftrag a2
        INNER JOIN shop_zahlungsarten sz2 ON sz2.id = a2.payment
        WHERE a2.status = '2'
        AND sz2.pay <> '1'
        ORDER BY a.date
        ;

        dabei ist zu beachten, dass jeder auftrag nur eine zahlungsart haben sollte. ist dies nicht der fall, muss man noch mal umstellen.

        Ilja