Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

Datensatz letzter Wochentag im Vormonat

Dieses Thema im Forum "MySQL und MariaDB" wurde erstellt von frandani, 2 Oktober 2015.

  1. frandani

    frandani Benutzer

    Ich habe eine MySql Datenbank in der sich für jeden Wochentag ausser SA und SO und Feiertage ein Datensatz befindet. Nun möchte ich jeweils am Ersten eines neuen Monats alle Datensätze des Vormonats bis auf den letzten Wochentag löschen.

    SELECT Datum, Wert FROM Werte WHERE Datum = (SELECT LAST_DAY(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH)));

    Mit diesem Befehl erhalte ich den Werte des letzten Tages im Monat. Das funktioniert aber nicht, wenn der letzte Tag des Monats ein Samstag oder Sonntag war (oder Feiertag), da dann kein Wert vorhanden ist.

    Seht ihr irgendeine Möglichkeit, wie man das bewerkstelligen könnte?
    Natürlich wäre es auch eine Möglichkeit, eine neue Tabelle zu erstellen und jeweils nur den gesuchten Wert in die neue Tabelle zu einzufügen.

    Beste Grüsse
    Dani
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Also, wenn der letzte Tag Sa, So oder Feiertag war, dann ist da kein Datensatz drin, ja? Und es soll immer 1 Tag, der letzte des Vormonates bleiben, ja?

    Für diese Tage sollen dann also gelöscht werden:

    Code:
    test=# create table tage as select '2015-09-15'::date + s as datum from generate_series(1,20) s;
    SELECT 20
    test=*# select * from tage;
      datum
    ------------
    2015-09-16
    2015-09-17
    2015-09-18
    2015-09-19
    2015-09-20
    2015-09-21
    2015-09-22
    2015-09-23
    2015-09-24
    2015-09-25
    2015-09-26
    2015-09-27
    2015-09-28
    2015-09-29
    2015-09-30
    2015-10-01
    2015-10-02
    2015-10-03
    2015-10-04
    2015-10-05
    (20 rows)
    
    test=*# select datum from tage where extract(month from datum) != extract(month from current_date) order by datum desc offset 1;
      datum
    ------------
    2015-09-29
    2015-09-28
    2015-09-27
    2015-09-26
    2015-09-25
    2015-09-24
    2015-09-23
    2015-09-22
    2015-09-21
    2015-09-20
    2015-09-19
    2015-09-18
    2015-09-17
    2015-09-16
    (14 rows)
    
    test=*# delete from tage where datum in (select datum from tage where extract(month from datum) != extract(month from current_date) order by datum desc offset 1);
    DELETE 14
    test=*# select * from tage;
      datum
    ------------
    2015-09-30
    2015-10-01
    2015-10-02
    2015-10-03
    2015-10-04
    2015-10-05
    (6 rows)
    
    
     
  3. frandani

    frandani Benutzer

    Danke für deine Antwort. Werde als Zwischenlösung mal jeweils am Wochenende den Wert des Vortages in die Datnebank schreiben.

    beste grüsse
    dani
     
  4. ukulele

    ukulele Datenbank-Guru

    In MSSQL könnte man das so lösen:
    Code:
    DELETE
    FROM   tabelle
    WHERE   datum < (
    
    SELECT   max(datum)
    FROM   tabelle
    WHERE   datepart(yyyy,datum) = datepart(yyyy,getdate())
    AND     datepart(mm,datum) = datepart(mm,getdate()) - 1
    
         )
    
    Und das ließe sich auf jedenfall in MySQL übersetzen, du musst nur die Funktionen datepart() und getdate() ersetzen, die eine hast du ja schon mit current_date().

    Aber Vorsicht: Beim Ausführen löscht du alles bis auf den letzten Eintrag des vorhergehenden Monats. Ich weiß nicht, ob nur der letzte des vorhergehenden Monats oder die jeweils letzen Einträge eines jeden Monats bestehen bleiben sollen. Letzteres könnte man aber auch leicht abbilden.
     
  5. frandani

    frandani Benutzer

    Hallo Ukulele

    Vielen Dank für deine Antwort. Ich habe nun eine Lösung, damit jeder Tag des Monats einen Wert hat, auch Wochenenden und Feiertage. Nun müsste eine Abfrage machen, bei der ich von allen bestehenden Monaten jeweils den Wert des letzten Tages erhalte. Also quasi wie diese Abfrage:
    SELECT Datum, Wert FROM Werte WHERE Datum = (SELECT LAST_DAY(DATE_ADD(CURRENT_DATE(), INTERVAL 1 MONTH)));

    Aber die Abfrage sollte den Wert für jeden Monat (jeweils immer den letzten Tag des Monats) zurückgeben und nicht nur für den letzten Monat. Ist das möglich?
     
  6. Distrilec

    Distrilec Datenbank-Guru

    Edit: Angepasst damit es auch Jahresübergreifend funktioniert...
    Code:
    Select datum
          ,wert
    From  werte
    Where datum In (Select Max(datum)
                    From   werte
                    Group  By Extract(Month From datum), Extract(Year From datum))
    Sowas in der Art sollte funktionieren...
    Keine Ahnung ob MySQL die Extract-Funktion kann... ^^
     
  7. frandani

    frandani Benutzer

    Habe es heute getestet. Die Funktion Extract ist in mysql möglich. Allerdings klappt es irgendwie doch nicht.

    Select Max(datum)
    From werte
    Group By Extract(Month From datum), Extract(Year From datum)

    Nur diese Abfrage gibt eine korrekt Antwort aus
    2015-01-30
    2015-02-27
    2015-03-31
    usw.

    Da an jedem Datum von verschiedenen Stationen Werte in die Datenbank geschrieben werden, habe ich die Abfrage oben wie folgt ergänzt:

    SELECT datum ,wert, station_id
    FROM werte
    WHERE station_id=1 AND
    datum IN(Select MAX(datum)
    FROM werte
    GROUP BY EXTRACT(Month From datum), EXTRACT(Year From datum))

    Wenn ich die Abfrage starte kommt keine Fehlermeldung, sondern es passiert einfach nichts und ich muss mysql unterbrechen.

    An was könnte das liegen?

    Vielen Dank für eure Hilfe
    Dani
     
  8. akretschmer

    akretschmer Datenbank-Guru

    Was genau suchst Du? Den letzten Tag des Monats? Dann ist das aber falsch, für den Januar und auch Februar.
     
  9. frandani

    frandani Benutzer

    Ich suche den letzten vorhandenen Eintrag eines Monats. Da aber nur an Wochentagen Einträge gemacht werden, kann es sein, dass der letzte Eintrag nicht der letzte Tag des Monats ist.
    Obengenannte Abfrage sollte also korrekt sein meines Erachtens.

    Die Frage ist noch, wie ich die Werte einer bestimmten Station dieser Daten erhalte.
     
  10. akretschmer

    akretschmer Datenbank-Guru

    Ah:

    Code:
    test=*# select extract(month from datum), max(datum) from (select datum, extract(dow from datum) as dow from (select ('2015-01-01'::date + s * '1day'::interval)::date datum from generate_Series(0,364)s) foo) bla where dow between 1 and 5 group by 1 order by 1;
     date_part |  max
    -----------+------------
      1 | 2015-01-30
      2 | 2015-02-27
      3 | 2015-03-31
      4 | 2015-04-30
      5 | 2015-05-29
      6 | 2015-06-30
      7 | 2015-07-31
      8 | 2015-08-31
      9 | 2015-09-30
      10 | 2015-10-30
      11 | 2015-11-30
      12 | 2015-12-31
    (12 rows)
    
    Zum zweiten Teil der Frage: mit WHERE.
     
  11. frandani

    frandani Benutzer

    Hallo am Wochenende nochmals versucht, aber leider klappt es immer noch nicht. Ich erhalte zwar mit einer Select Abfrage die gewünschten Daten
    Select MAX(datum)
    FROM werte
    GROUP BY EXTRACT(Month From datum), EXTRACT(Year From datum)

    Aber wie oben bereits geschrieben klappt es nicht, diese Daten auszugeben mit dem IN Statement. z.b. Wenn ich das Datum von Hand eintrage:

    SELECT datum ,wert, station_id
    FROM werte
    WHERE station_id=1 AND
    datum IN ('2015-01-30')

    Dann klappt es, aber mit dieser Abfrage läufts nicht
    SELECT datum ,wert
    FROM werte
    WHERE
    datum IN(Select MAX(datum)
    FROM werte
    GROUP BY EXTRACT(Month From datum), EXTRACT(Year From datum))
     
  12. Distrilec

    Distrilec Datenbank-Guru

    Code:
    SELECT datum ,wert
    FROM werte
    WHERE
    datum IN(Select MAX(datum)
    FROM werte
    GROUP BY EXTRACT(Month From datum), EXTRACT(Year From datum)) 
    Er zeigt einfach nichts an? Oder dauert es einfach nur extrem lange?
    Wieviele Datensätze hast du denn in der Tabelle?
     
  13. frandani

    frandani Benutzer

    Es sind 69'000 Datensätze in der Tabelle und das ganze läuft auf einem Raspberry Pi. Habe nun mal mit dem Befehl "show processlist" gecheckt und gesehen, dass die Abfrage seit nun 24h läuft.
    Somit wird das ganze vermutlich ein Performanceproblem sein.
    Werde das ganze Mal mit weniger Datensätzen versuchen.
     
  14. Distrilec

    Distrilec Datenbank-Guru

    Das ist ja nix... Also irgendwo ist da bei dir der Wurm drinn...

    Was passiert denn wenn du auf Station_Id eingrenzt?
    Code:
    SELECT datum ,wert
    FROM werte
    WHERE station_id = '1'
    And datum IN(Select MAX(datum)
    FROM werte
    Where station_id = '1'
    GROUP BY EXTRACT(Month From datum), EXTRACT(Year From datum)) 
     
  15. frandani

    frandani Benutzer

    Es passiert das Gleiche. Keine Fehlermeldung, aber es läuft bereits seit 25 min.
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden