Seite 1 von 1

Datenbank Requestfrage Wie kann ich....

Verfasst: 30.06.2020 09:31
von Bisonte
Hallo. Ich hab da mal eine Frage zu einem Datenbank Request (SQLite)...

Ich habe folgende tabelle (gekürzt)

Code: Alles auswählen

konto jahr monat wert
1000  2020   2   100
1200  2020   2   1000
1300  2020   2   10

1000  2020   1   200
>1200  nicht vorhanden
1300  2020   1   20

1000  2019   12  300
>1200 nicht vorhanden
1300  2019   12  30

1000  2019   11  400
1200  2019   11  4000
1300  2019   11  40
Ich möchte nun den wert aller konten in eine map einlesen. und zwar nur für einen Monat eines Jahres.
Das ist nicht weiter wild. Interessant ist nun aber die Frage : Wie bekomme ich den älteren Wert eines Kontos, wenn der gesuchte nicht vorhanden ist ?

Beispiel zu der Tabelle :
Die Werte aller Konten des Jahres 2020 und des Monats 1 sollen eingelesen werden
Also bekommen ich mit "SELECT * FROM wertung WHERE monat = 1 AND jahr = 2020"
die Map :
Wert("1000") = 200
Wert("1300") = 20
Da hier die 1200 nicht vorhanden ist, brauche ich den "nächsten" älteren wert....
also Wert("1200") = 4000

Wie müsste ich die WHERE Klausel "designen" damit ich auf das gewünschte Ergebnis komme ?

Angemerkt wäre noch, dass es durchaus sein kann, dass mehrere Monate kein Eintrag eines Kontos existiert.
Und auf 0 kann icch nicht testen, da es durchaus sein kann das dieses Konto ein einem Monat keinen Wert hat...
(weil ein Schuft das Ding leergeräumt hat ;) )

Grund des ganzen... Ich trage nicht jeden Monat alle Konten die existieren in die Datenbank, damit nicht unnötige Daten in der
DB liegen... es können bis zu 13.000 konten sein, und die jeden monat eintragen obwohl keine bewegung stattgefunden hat,
wäre der overkill ....

Re: Datenbank Requestfrage Wie kann ich....

Verfasst: 30.06.2020 10:29
von NicTheQuick
Zunächst mal wäre es praktisch, wenn Monat und Jahr ein richtiger Datumsstempel wäre, auf dem man mit Vergleichsoperatoren arbeiten kann. Denn sonst ist es schwer etwas zu formulieren, was Zeilen vor einer bestimmten Jahr/Monat-Kombination selektiert.

Ich habe jedenfalls sowas ähnliches schon mal bei einem Kundenprojekt machen müssen, allerdings mit der Oracle Datenbank und nicht in Purebasic. Ich habe allgemein noch nie mit Datenbanken in Purebasic gearbeitet. Könntest du dein Beispiel für mich lauffähig machen, damit ich mal herumprobieren kann?

Re: Datenbank Requestfrage Wie kann ich....

Verfasst: 30.06.2020 15:39
von H.Brill
Man könnte auch mit dem Datum rechnen.
So was ähnliches hatte ich schon mal mit einer
dBase - Tabelle gemacht, wo das Datum als
Datenbankformat (YYYYMMDD) vorlag.

Dazu müßte aber dein Monat immer zweistellig sein
1000 2020 2 100 -> 1000 202002 100. Wenn ein Monat
nur einstellig ist, dann eine 0 vorne dran. Aus z.B. 2 mache 02.
Jahr und Monat müßten dann als EIN Datenfeld existieren.
Also Jahr und Monat zusammenziehen (nicht addieren,
sondern 2 Strings aneinander).

Dann ist ist das älteste immer das kleinste und das Größte das aktuellste.

Wäre evtl. mal ein Ansatz für eine Lösung.

Re: Datenbank Requestfrage Wie kann ich....

Verfasst: 30.06.2020 16:52
von NicTheQuick
Ich mal was gefiddlet: http://sqlfiddle.com/#!9/dda11/7/0

Das nutzt allerdings MySQL 5.6 und nicht SQLite. Ich hoffe damit geht es trotzdem. Wichtig ist jedenfalls wegen der MAX-Funktion oder allem anderen, was mit Sortieren zu hat, dass das Datum in einer Spalte ist. Ich habe es jetzt durch einen Integer simuliert. Hübscher wäre es natürlich einen echten Datumstyp zu nutzen.

Falls das Fiddle nicht mehr geht. Hier die Quellcodes:

Schema und Inhalt:

Code: Alles auswählen

CREATE TABLE T
    (`konto` int, `date` int, `wert` int)
;
    
INSERT INTO T
    (`konto`, `date`, `wert`)
VALUES
    (1000, 202002, 100),
    (1200, 202002, 1000),
    (1300, 202002, 10),
    (1000, 202001, 200),
    (1300, 202001, 20),
    (1000, 201912, 300),
    (1300, 201912, 30),
    (1000, 201911, 400),
    (1200, 201911, 4000),
    (1300, 201911, 40)
;
SQL-Select für das Datum Januar 2020:

Code: Alles auswählen

SELECT
  t.*
FROM
  T t
    INNER JOIN
      (
        SELECT
          konto,
          MAX(date) AS date
        FROM
          T
        WHERE
          date <= 202001
        GROUP BY konto
      ) s
      ON
            t.konto = s.konto
        AND t.date = s.date;
Ergebnis:

Code: Alles auswählen

| konto |   date | wert |
|-------|--------|------|
|  1000 | 202001 |  200 |
|  1300 | 202001 |   20 |
|  1200 | 201911 | 4000 |

Re: Datenbank Requestfrage Wie kann ich....

Verfasst: 30.06.2020 17:13
von H.Brill
NicTheQuick :
Ja, genau so hatte ich das mit dem Datum gemeint.
Und als Zahl gespeichert ist noch besser.

Damit kann man dann alles anwenden : =, <, >, >=, <= <>