SQlite Abfrage

Alles rund um die Programmierung mit Qt
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Hallo Christian,

so wie ich das sehe, würde deine Abfrage ja auch Problemlos mit CURRENT_TIMESTAMP zurecht kommen.

So hätte ich dann in der Query-Variablen alle Buchungen der betreffenden Tage drin, oder?

Übrigens danke für den Link. Das Zeug müsste ich dringend mal durcharbeiten. :?

Gruß
Chris
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Hallo zusammen,

ich habe mich mal an einer Fuction versucht.
Das Ergebnis ist leider Null.

Code: Alles auswählen

double bestellProg(const QString &ktoTAB)
    {
            connOpen();
            QSqlQuery prognose;
            prognose.prepare(QString("SELECT Buchungswert FROM %1 ORDER BY Datum DESC LIMIT 2 AND Buchungsart = AB").arg(ktoTAB));
            prognose.exec();
            prognose.last();
            double verbrauch = prognose.toDouble();
            connClose();
            qDebug()<< verbrauch;

            return verbrauch;
    }
So habe ich es auch mal versucht. Leider auch Ergebnis = Null.

Code: Alles auswählen

double bestellProg(const QString &ktoTAB)
    {
            connOpen();
            QSqlQuery prognose;
            prognose.prepare(QString("SELECT * FROM %1 ORDER BY Datum DESC LIMIT 2 AND Buchungsart = AB").arg(ktoTAB));
            prognose.exec();
            prognose.last();
            double verbrauch = prognose.value("Buchungswert").toDouble();
            connClose();
            qDebug()<< verbrauch;

            return verbrauch;
    }
Irgendwo hab ich wohl wieder einen Bock geschossen. :(
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Hallo Christian,
die Abfrage funktioniert leider nicht ganz so gut.

Code: Alles auswählen

SELECT ... FROM tabelle ORDER BY <zeitspalte> DESC LIMIT 3
Habe jetzt mal meine 2. Bedingung (Suche nach AB) weggelassen. Jetzt bringt mir deine Abfrage auch einen Wert.
Leider holt sie ja immer nur einen Wert. Immer den, den ich ihr mit LIMIT x sage.
Sie soll aber alle Werte aus der Spalte "Buchungswerte" addieren, die in den letzten drei Buchungstagen vor HEUTE gebucht wurden.

Beispiel:
Heute ist der 16.
Gebucht wurde am
09. --> 500kg
10. --> 200kg
10. --> 300kg
12. --> 200kg
12. --> 400kg
14. --> 200kg

16. --> 100kg

Die grünen Werte müssten addiert werden.

Ist wahrscheinlich gar nicht so einfach umzusetzen,oder?

Viele Grüße
Chris
MichaelS
Beiträge: 240
Registriert: 27. Dezember 2005 12:49

Re: SQlite Abfrage

Beitrag von MichaelS »

Moin,

ich hatte schon einmal darauf hingewiesen, dass Du zumindest ein rudimentäres Fehlerhandling implementieren solltest. Das von Dir übergebene SQL-Statement

Code: Alles auswählen

prognose.prepare(QString("SELECT Buchungswert FROM %1 ORDER BY Datum DESC LIMIT 2 AND Buchungsart = AB").arg(ktoTAB));
ist kein gültiges SQL und führt dazu, dass exec() und last() fehlschlagen. Da Du das aber nicht prüfst, bekommst Du davon nichts mit und wunderst Dich dann über 0-Werte.

Gruß Michael
MichaelS
Beiträge: 240
Registriert: 27. Dezember 2005 12:49

Re: SQlite Abfrage

Beitrag von MichaelS »

Leider holt sie ja immer nur einen Wert. Immer den, den ich ihr mit LIMIT x sage.
Sie soll aber alle Werte aus der Spalte "Buchungswerte" addieren, die in den letzten drei Buchungstagen vor HEUTE gebucht wurden.
Woher soll die Datenbank denn wissen, dass sie die Werte addieren soll, wenn Du es ihr nicht sagst?

Code: Alles auswählen

select sum(Buchungswert) from (select Buchungswert FROM meineTabelle order by Datum desc LIMIT 3)
Ich kann aber gerade nicht testen, ob das auch mit Sqlite funktioniert. Und wenn es sich nicht direkt mit SQL erschlagen lässt, dann musst Du die Werte eben zu Fuß addieren:

Code: Alles auswählen

query.prepare( ... )

if ( !query.exec() )
{
  //Fehlermeldung ausgeben
  return;
}
double summe = 0.0;

/* Mit Sqlite schlägt next() fehl, wenn nicht zuerst mit first() der erste Satz geholt wurde */
if ( !query.first() )
  return;

summe = query.value( 0 ).toDouble();
while( query.next() )
  summe += query.value( 0 ).toDouble();
}
1
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Hallo Michael,

hast ja Recht, so viel Zeit muss sein. Ohne Fehlerhandling kommt man nie dahinter.

Ich habe jetzt, dank deiner großen Unterstützung folgende Funktion erstellt:

Code: Alles auswählen

double bestellProg(const QString &ktoTAB)
    {
            connOpen();
            QSqlQuery prognose;
            prognose.prepare(QString("SELECT Buchungswert FROM %1 ORDER BY Datum DESC LIMIT 3").arg(ktoTAB));
            prognose.exec();
            if ( !prognose.exec() )
            {
              qDebug() << "Abfrage gescheitert!";
              return 0;
            }
            prognose.last();
            double verbrauch = 0.0;
            if ( !prognose.first() )
              return 0;
            verbrauch = prognose.value( 0 ).toDouble();
            while( prognose.next() )
                verbrauch += prognose.value( 0 ).toDouble();
            connClose();
            qDebug()<< verbrauch;

            return verbrauch;
    }
Die bringt mir die Summe aus den letzten 3 Buchungen.
Das klappt nun schon mal hervorragend.

Wie kann man es nun anstellen, dass mir die Summe aller Buchungen der letzten 3 Buchungstage gebildet wird.
Nochmal ein Beispiel:
Heute ist der 16.
Gebucht wurde am
09. --> 500kg
10. --> 200kg
10. --> 300kg
12. --> 200kg
12. --> 400kg
14. --> 200kg

16. --> 100kg
Jetzt müssten nur die grünen Zahlen (die der letzten drei Buchungstage, außer heute) addiert werden.
Somit müsste verbrauch == 1300 sein.
Mir ist das im Moment echt noch schleierhaft, wie ich das programmieren soll.

Übrigens, kennt jemand ein gutes deutsches Qt-Buch? Ist bestimmt eine häufig gestellte Frage, aber wenn ich mir das Ergebnis meiner bisherigen Recherche ansehe und die Rezensionen anderer Leser in mein Urteil einfließen lasse, gibt es kein gutes deutsches Buch.
Seht ihr das genauso?

Viele Grüße und noch mal vielen Dank für euer Unterstützung bei meinem kleinen Projekt.
Chris
Partsoft
Beiträge: 6
Registriert: 8. März 2016 17:09

Re: SQlite Abfrage

Beitrag von Partsoft »

Übrigens, kennt jemand ein gutes deutsches Qt-Buch? Ist bestimmt eine häufig gestellte Frage, aber wenn ich mir das Ergebnis meiner bisherigen Recherche ansehe und die Rezensionen anderer Leser in mein Urteil einfließen lasse, gibt es kein gutes deutsches Buch.
Seht ihr das genauso?
https://www.amazon.de/gp/product/013235 ... UTF8&psc=1
https://www.amazon.de/gp/product/032163 ... UTF8&psc=1

Diese beiden Klassiker (noch zu Qt4) sind die besten Bücher die ich kenne und gab es auch in deutscher Fassung. Ab und zu werden diese noch bei Amazon oder eBay angeboten, dann allerdings zu horrenden Preisen. Ich hab da schon Angebote über 300 Euro gesehen :shock:

Ich habe beide Bücher (in der englischen Originalausgabe) im Regal stehen und zusätzlich als eBook auf dem Kindle immer dabei.
https://www.partsoft.de
Softwareentwicklung und Vertrieb
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Hi Sascha,

ist ja der Hammer. Hab gerade mal ein bisschen in Google gestöbert. Die wollen tatsächlich für gebrauchte deutsche Ausgaben bis über 500 Euro haben.
Bei Amazon habe ich eine gebrauchte deutsche Fassung für 99 Euro gefunden.
Hmm, das ist schon ganz schön happig.
Ich schau gerade nach einer Möglichkeit, dass der Amazon Cloud Reader vom Englischen ins Deutsche übersetzt.
Wenn das geht, dann besorg ich mir die englischen Fassungen.

VG und danke für den Tipp

Chris
MichaelS
Beiträge: 240
Registriert: 27. Dezember 2005 12:49

Re: SQlite Abfrage

Beitrag von MichaelS »

Wie kann man es nun anstellen, dass mir die Summe aller Buchungen der letzten 3 Buchungstage gebildet wird.
Nochmal ein Beispiel:
Heute ist der 16.
Gebucht wurde am
09. --> 500kg
10. --> 200kg
10. --> 300kg
12. --> 200kg
12. --> 400kg
14. --> 200kg
16. --> 100kg
Jetzt müssten nur die grünen Zahlen (die der letzten drei Buchungstage, außer heute) addiert werden.
Somit müsste verbrauch == 1300 sein.
Mir ist das im Moment echt noch schleierhaft, wie ich das programmieren soll.
Um das Problem zu lösen, musst Du zunächst das Datum der letzten drei Buchungstagse ermitteln und dann alle Sätze holen, deren Datum diesem Buchungsdatum entspricht. Etwa so :

Code: Alles auswählen

SELECT buchungswert
     FROM meineTabelle 
     WHERE datum IN (SELECT distinct datum 
                  FROM meineTabelle 
                  WHERE datum < date('now') order by datum desc limit 3 ) ;
 
Dann gehst Du mit einer Schleife durch die Ergebnismenge und addierst die Werte.

Gruß Michael
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Hi Michael,

ich habe die Funktion jetzt so umgebaut:

Code: Alles auswählen

double bestellProg(const QString &ktoTAB)
    {
            connOpen();
            QSqlQuery prognose;
            prognose.prepare(QString("SELECT Buchungswert FROM %1 WHERE Datum IN (SELECT distinct Datum FROM %1 WHERE Datum < date( 'now' ) ORDER BY Datum DESC LIMIT 3").arg(ktoTAB));
            prognose.exec();
            if ( !prognose.exec() )
            {
              qDebug() << "Abfrage gescheitert!";
              return 0;
            }
            prognose.last();
            double verbrauch = 0.0;
            if ( !prognose.first() )
              return 0;
            verbrauch = prognose.value( 0 ).toDouble();
            while( prognose.next() )
                verbrauch += prognose.value( 0 ).toDouble();
            verbrauch = verbrauch / 3;
            connClose();
            qDebug()<< verbrauch;

            return verbrauch;
    }
Es kommt die qDebug-Meldung: Abfrage gescheitert!
Auch wenn ich die Funktion so verändere, dass der Tabellenname nicht variabel ist, kommt die gleiche Meldung. Damit sollte es also nichts zu tun haben.
Die Tabelle ist folgendermaßen aufgebaut:
ID (int autoincrement) Datum (CURRENT_TIMESTAMP(yyyy-mm-dd hh:mm:ss)) Buchungsart (z.B. AB, ZU, Inventur usw) Buchungswert (z.B. 600,7 usw.(FLOAT)) Bestand(z.B. 23001,5(FLOAT))

Weiß jemand, warum das nicht funktioniert?
Das ist bis jetzt immer dann passiert, wenn man eine zusätzliche SELECT-Abfrage in die Abfrage integriert. Vielleicht hat es etwas mit den Anführungszeichen zu tun? Kann das sein, dass ich sie falsch setze?

Gruß
Chris
MichaelS
Beiträge: 240
Registriert: 27. Dezember 2005 12:49

Re: SQlite Abfrage

Beitrag von MichaelS »

Hallo,

Bei Deinem Umbau hast Du einen Syntax-Fehler eingebaut, denn es fehlt die schließende Klammer des Subselects.

Gruß Michael
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Hi Michael,

stimmt, da hab ich ne Klammer vergessen...
Ich habe sie jetzt an zwei Stellen ausprobiert.
Einmal direkt hinter date('now') und direkt vor das abschließende Anführungszeichen.
Beides ergab das Gleiche, nämlich wieder nur die Addition der Zeilen, die ich in DESC LIMIT vorgebe.

Kann man die Abfrage nicht so umgestalten, dass einfach alles gesammelt wird, was in den Datumsbereich date('now') - "3 Tage" reinfällt.
Idealerweise (in Excel geht das) date('now') - 3 Arbeitstage.

Viele Grüße
Chris
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Nachtrag:
In Excel muss das ganze dann 3 x durchlaufen.
1: heute() - 1 = xyz <-- suche alles mit diesem Datum
2: heute() - 2 = xyz <-- suche alles mit diesem Datum
3: heute() - 3 = xyz <-- suche alles mit diesem Datum

So ähnlich läuft das dort. Müsste ich noch mal nachsehen, wie ich das "zusammengeschustert" hab. Jedenfalls gab es drei Hilfszellen, s.o.

Gruß
Chris
MichaelS
Beiträge: 240
Registriert: 27. Dezember 2005 12:49

Re: SQlite Abfrage

Beitrag von MichaelS »

Code: Alles auswählen

kann man die Abfrage nicht so umgestalten, dass einfach alles gesammelt wird, was in den Datumsbereich date('now') - "3 Tage" reinfällt.
Idealerweise (in Excel geht das) date('now') - 3 Arbeitstage.
Dann würdest Du nur die Werte bekommen, die in den letzten drei Tagen gebucht wurden, also ausgehend von heute ( 24.01. ) alles, was zwischen dem 21.01 uind 24.01. gebucht wurde. Wenn aber die letzten Buchungen am 18./19. und 20.1. waren, würdest Du die damit nicht bekommen. Das war aber - wenn ich Dich richtig verstanden habe, gefordert.
ChrisRoo
Beiträge: 19
Registriert: 14. Januar 2017 16:37

Re: SQlite Abfrage

Beitrag von ChrisRoo »

Hi Michael,
um es auf den Punkt zu bringen, hatte ich einen kleinen Denkfehler in meinem Wunsch.

Fakt ist, ich muss den Durchschnittsverbrauch der letzten drei Arbeitstage ermitteln.
Wenn an diesen Tagen nichts gebucht wurde, dann ist eben auch im Moment kein Verbrauch.
Ich mache das Ganze, weil ich hier 6 Silos habe. Ich muss der Kosten wegen, immer große Mengen bestellen. Leider hat das Material Lieferzeit, sodass ich 10 Tage im voraus wissen muss, wann das Silo soweit "leer" ist, dass ich die bestellte Menge unterbringe. Wenn das nicht funktioniert, dann wird es teuer. Also hab ich mir so eine Art Artikelkonto mit Bestellprognose in Excel gebaut. Das ist aber wenig professionell und setzt von meinen Mitarbeitern immer ein großes Verständnis für dass, was sie da gerade eintragen, voraus. Schnell hat man mal vergessen zu speichern und schon stimmt nichts mehr.

Deswegen möchte ich das jetzt mit Qt erstellen. Zum Buchen geht ein Eingabeformular auf und mit dem Bestätigen steht es in der Datenbank.

Viele Grüße und noch Mal sorry...
Chris
Antworten