Summenproblem (MariaDB)

  • Hi,
    mit folgender Abfrage:

    erhalte ich wunschgemäß die Tagessumme:


    generated 2018-11-17 13:42:28 by HeidiSQL 9.4.0.5125

    Wie bekomme ich nun daraus eine Monatssumme?

  • [INDENT] Vielen Dank. Hatte ich genau so gemacht und dann festgestellt, dass ich andere Tagessummen erhalte, wie bei der Einzelberechnung...
    Ich habe daher ein ganz anderes Problem.
    Zum Berechnen der Rechnungen brauche ich 3 Tabellen.
    In der Tabelle pakete befinden sich u.a. die Kundennummer T.po (natürlich als VARCHAR...), der Zeitpunkt der Rechnungserstellung T.ausgang(Datetime) und die Größe T.size (VARCHAR).
    In der Tabelle preise befinden sich die Größe P.groesse (VARCHART) und die Preise P.preis ( VARCHART, was sonst..).
    In der Tabelle rechnungen befinden sich Rechnungsnummer R.rechnungsnr (selbstredend VARCHART) und Kundennummer R.kundennr (VARCHART) sowie Rechnungsdatum R.rechnungsdatum (wirklich DATE, da muss jemand wohl nen Geistesblitz gehabt haben).
    Mit meiner obigen Abfrage bekomme ich zwar den richtigen Tagessaldo, allerdings fehlerhafte Rechnungssummen, wenn ein Kunde mehrere Rechnungen pro Tag erhält. Es werden pro Rechnung alle Einzelsummen addiert. Wie bekomme ich das hin?
    [/INDENT]

    • Offizieller Beitrag

    Also für mein Verständnis ist das Konzept zu überdenken.
    Wenn Du Verkäufe hast, hast Du auch Artikel und Kunden. Diese drei Dinge sind imho getrennt voneinander zu betrachten.

    Deine Tabelle Pakete ist für mich ebenfalls unklar, u.a. auch weil ich mich frage, was das Datum der Rechnungsstellung darin verloren hat? Das gehört einzig in die Tabelle Rechnungen.

    Eine Tabelle Rechnung ( Invoices ) wäre im ersten Step bei mir so in etwas aufgeaut:


    Das sind die wichtigsten Kerninformationen, die mir adhoc einfallen und aus meiner Sicht grundsätzlich Rechnungsrelevant sind.
    Enthaltene Artikel gehören für mich wieder in eine separate Tabelle, die über die InvoiceId verknüpft werden kann.

    Da Du aber nur den Umsatz benötigst, reicht die Invoices-Tabelle vollkommen aus.
    Jetzt musst Du nur noch je nach Auswertung die Spalte InvoiceDate auf das Tagesdatum oder auf den Monat runterbrechen.
    Willst Du beides in einer Auswertung haben, würde ich UNION verwenden.

  • Jep, würde ich auch so oder doch so ähnlich aufbauen. Nütz mir aber nichts, da ich mich mit diesen Vorgaben herumschlagen darf.
    Warum sich das Datum der Rechnung nicht in der rechnungen Tabelle befindet, ist mir auch rätselhaft. Aber so ist das halt.
    Ändern will ich da nur sehr ungern etwas, da mit diesen Tabellen alle möglichen Abfragen, Auswertungen Kron-Jobs etc. verknüpft sind - frei nach dem Motto: Never change a running system.

    Nichtsdestotrotz habe ich noch mein Problem mit den 'falschen' Mehrfachrechnungen. Ich mache ja eigentlich nichts weiter als die Summen zu bilden. Ich erhalte ja mit der obigen Abfrage trotz teilweiser falscher Rechnungssummen den richtigen Tagessaldo (Keine Berücksichtigung der einzelnen Rechnungen bei UNION). Wenn ich ne Abfrage mit GROUP BY WITH ROLLUP mache, entspricht das Ergebnis zwar der Summe der Einzelrechnungen, ist damit aber leider falsch. Wie bekomme ich korrekte Rechnungssummen bei Mehrfachrechnungen?

    Beispiel:
    02.11.2018 26191 2552 13,00 korrekt wäre 3,50
    02.11.2018 26192 2552 13,00 korrekt wäre 3,00
    02.11.2018 26193 2552 13,00 korrekt wäre 3,50
    02.11.2018 26194 2552 13,00 korrekt wäre 3,00

    Ich habe also 4 Rechnungen für KdNr 2552, die ja auch nach meinen Bedingungen richtig berechnet werden, aber halt leider das falsche Ergebnis liefern. Wie mache ich das richtig?
    Also Bedingung benutze pro Rechnung nur das gleiche DATETIME (T.ausgang) oder ähnlich...

    4 Mal editiert, zuletzt von Schnurze (18. November 2018 um 21:57)

    • Offizieller Beitrag

    Never change a running System sollte aber nur bei sinnvollen Systemen gelten...
    Wenn Du auf der Basis weitermachen möchtest, kommst Du nicht umhin, uns einen echten Aufbau ( nicht nur kurz dargestellt ) Deiner Datenbanktabellen vorzustellen.
    Deine kurzen Beispiele sind nicht wirklich nützlich, um bei der Grundlage helfen zu können.

  • Also bitteschön:

    TABLE pakete (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `po` INT(30) NULL DEFAULT NULL, das ist die Kundennummer
    `size` VARCHAR(100) NULL DEFAULT NULL,
    `status` INT(2) NULL DEFAULT NULL, das ist ein Schalter: 0 Art. ist nicht da, 1 Art. ist da
    `lagerort` VARCHAR(100) NULL DEFAULT NULL,
    `eingang` DATETIME NULL DEFAULT NULL,
    `ausgang` DATETIME NULL DEFAULT NULL, Zeitpunkt an dem die Rechnung erstellt wurde
    `aname` VARCHAR(250) NULL DEFAULT NULL,
    `aadress` VARCHAR(250) NULL DEFAULT NULL,
    `aplz` VARCHAR(100) NULL DEFAULT NULL,
    `aort` VARCHAR(250) NULL DEFAULT NULL,
    `aland` VARCHAR(250) NULL DEFAULT NULL,
    `quittung` INT(1) NULL DEFAULT NULL,
    `entsorgung` VARCHAR(15) NULL DEFAULT NULL das ist eine Zusatzleistung in Euro
    )

    TABLE preise (
    `id` INT(10) NOT NULL,
    `groesse` VARCHAR(100) NOT NULL DEFAULT '',
    `preis` VARCHAR(10) NULL DEFAULT NULL
    )

    TABLE rechnungen (
    `rechnungsnr` INT(20) NOT NULL AUTO_INCREMENT,
    `kundennr` INT(20) NOT NULL,
    `file` VARCHAR(300) NOT NULL, hier steht der Speicherort des PDFs der Rechnung
    `rechnungsdatum` DATE NOT NULL
    )

    Ich hab mir auch schon gewünscht, diejenigen in den Hintern zu treten, die das verbrochen haben. Und in der Datenbank sind gute 100 Tabellen, die nach der gleichen Logik aufgebaut sind. Und mit PHP und Wordpress veröffentlicht. Und funktionierend. Probleme gibts halt nur bei Änderungen / Erweiterungen.

    Einmal editiert, zuletzt von Schnurze (19. November 2018 um 09:41)

  • Jep preise.groesse = pakete.size,
    rechnungen.kundennr = pakete.po
    date(pakete.ausgang) = rechnungen.rechnungsdatum,

    wie gesagt, meine obige Abfrage läuft ja soweit...

  • Also um das Thema nochmals aufzugreifen vereinfache ich mal:
    in der Tabelle 1 habe ich ein Datetime Feld, eine KdNr und ein Betrag.
    in der Tabelle 2 habe ich ein Datum , eine KdNr und eine ReNr.
    Die Abfrage soll nun nur alle ReNr, KdNr, Beträge pro Tag auflisten.
    Mein Problem sind halt mehrere gleiche Kunden an einem Tag,
    also wie bekomme ich es hin, dass die erste ReNr pro Kunde nur dem ersten Datetime zugeordnet wird?

  • OK - Danke für die Hilfe, habe das jetzt selbst lösen können. Falls jemand wissen will wie, hier meine Lösung:
    Die Rechnungsnummer (auto_increment) aus der 2. Tabelle ist ja via dem Feld 'Ausgang' (DateTime) mit der 1. Tabelle verknüpft.
    Also TEMPORARY TABLE aus 1. Tabelle mit Summieren/Gruppieren und Ordnen auf 'Ausgang', dann ID Spalte (auto_increment) hinzufügen.
    TEMPORARY TABLE aus 2. Tabelle ordnen nach Rechnungsnummer, dann ebenfalls ID Spalte hinzufügen.
    Alles natürlich für das gleiche Datum und dann Abfrage nach gleicher ID et voila....
    Es Funktioniert genau so, wie es soll. Wenn jemand was einfacheres, besseres oder/und eleganteres weiss, einfach nur posten.

    • Offizieller Beitrag
    Zitat

    Die Rechnungsnummer (auto_increment) aus der 2. Tabelle ist ja via dem Feld 'Ausgang' (DateTime) mit der 1. Tabelle verknüpft.

    Rechnungsnummer => INT, Ausgang => DateTime
    Wenn Du damit Ergebnisse erhältst, würde ich denen nicht vertrauen... Das versuch mal mit einem anderen DBMS. MySQL is dafür bekannt, Fehler auch gern mal durch Zufallsergebnisse zu vertuschen...

    Btw., anstelle von TEMPORARY_TABLE würde ich eher VIEWS granular einsetzen und diese abfragen.

  • Sollte so doch auch eigentlich mit jeder anderen DBMS funzen: Die Rechnungsnummer wird aufgrund des DateTimestamps erstellt, also mehrere gleiche DateTime = eine Rechnungnummer (mit mehreren Art.), nächste DateTime = nächste Rechnungsnummer, ergo gleichviele Datensätze in beiden Tabellen (bei entsprechender Summierung) und gleiche Sortierung, wenn einmal nach DateTime und bei der anderen nach Rechnungsnummer sortiert wird.

    • Offizieller Beitrag
    Zitat

    Die Rechnungsnummer wird aufgrund des DateTimestamps erstellt

    Aus betriebswirtschaftlicher Sicht nicht erlaubt, aber könnte zumindest technisch hinhauen.
    Dennoch ist das Konzept Mist, vielleicht solltest Du mal darüber nachdenken, das umzubauen, oder hängen da andere größere Systeme mit dran?