Dynamische Datumsrange abhängig das aktuellen Tages

TurboKanne

Benutzer
Beiträge
5
Hallo, ich habe vieles zum Thema Date / Datum / Datums-Function gesehen, gelesen und ausprobiert. Aber meine mySQL-Abfrage will nicht so recht klappen. Ich habe folgendes vor:

SELECT * FROM `daten` WHERE IF (Day(now()) > 27, daten.datum BETWEEN '27.diesen Monats' AND NOW(), daten.datum BETWEEN '27.des letzten Monats‘ AND NOW())

Es soll also nach dem 27. eines Monats die Daten aus dem Zeitraum vom 27.des Vormonats bis heute abgefragt werden. Nach dem 27 sollen die Daten das aktuellen Monats abgefragt werden.

Plastischer - ein paar Beispiele

Heute ist 29.Mai - Abfrage soll Daten ausgeben zwischen 27.Mai und heute
Heute ist 01.Juni - Abfrage soll Daten ausgeben zwischen 27.Mai und heute
Heute ist 19.Mai - Abfrage soll Daten ausgeben zwischen 27.April und heute
Heute ist 22.Januar 2017 - Abfrage soll Daten ausgeben zwischen 27.Dezember 2016 und heute

Wie gestalte ich nun die beiden rot gekennzeichneten Bereiche in meiner SQL-Query? Habe es bislang statisch gemacht und mit festen Datumsangaben YYYY-MM-DD funktioniert es.

Würde mich über Hilfe sehr freuen.
 
Werbung:
Es soll also nach dem 27. eines Monats die Daten aus dem Zeitraum vom 27.des Vormonats bis heute abgefragt werden. Nach dem 27 sollen die Daten das aktuellen Monats abgefragt werden.

Richtig sollte es heißen: Es soll vor bis einschließlich dem 27. eines Monats die Daten aus dem Zeitraum vom 27. des Vormonats bis heute abgefragt werden. Nach dem 27. sollen die Daten das aktuellen Monats abgefragt werden.
 
Code:
SELECT *
FROM daten
WHERE datum BETWEEN
    IF( DAY(NOY()) > 27
        , DATE(NOW() - INTERVAL 1 MONTH - DAY(NOW()) + INTERVAL 27 DAY)
        , DATE(NOW() - DAY(NOW()) + INTERVAL 27 DAY)
    )
AND
    NOW();
 
Zuletzt bearbeitet:
Okay, mit PostgreSQL.

Ich habe mal diese Testdaten:

Code:
test=# select * from turbokanne where datum >= '2017-04-01';
 id  |  datum   
-----+------------
  91 | 2017-04-01
  92 | 2017-04-02
  93 | 2017-04-03
  94 | 2017-04-04
  95 | 2017-04-05
  96 | 2017-04-06
  97 | 2017-04-07
  98 | 2017-04-08
  99 | 2017-04-09
 100 | 2017-04-10
 101 | 2017-04-11
 102 | 2017-04-12
 103 | 2017-04-13
 104 | 2017-04-14
 105 | 2017-04-15
 106 | 2017-04-16
 107 | 2017-04-17
 108 | 2017-04-18
 109 | 2017-04-19
 110 | 2017-04-20
 111 | 2017-04-21
 112 | 2017-04-22
 113 | 2017-04-23
 114 | 2017-04-24
 115 | 2017-04-25
 116 | 2017-04-26
 117 | 2017-04-27
 118 | 2017-04-28
 119 | 2017-04-29
 120 | 2017-04-30
 121 | 2017-05-01
 122 | 2017-05-02
 123 | 2017-05-03
 124 | 2017-05-04
 125 | 2017-05-05
 126 | 2017-05-06
 127 | 2017-05-07
 128 | 2017-05-08
 129 | 2017-05-09
 130 | 2017-05-10
 131 | 2017-05-11
 132 | 2017-05-12
 133 | 2017-05-13
 134 | 2017-05-14
 135 | 2017-05-15
 136 | 2017-05-16
 137 | 2017-05-17
 138 | 2017-05-18
 139 | 2017-05-19
 140 | 2017-05-20
 141 | 2017-05-21
 142 | 2017-05-22
 143 | 2017-05-23
 144 | 2017-05-24
 145 | 2017-05-25
 146 | 2017-05-26
 147 | 2017-05-27
 148 | 2017-05-28
 149 | 2017-05-29
 150 | 2017-05-30
 151 | 2017-05-31
(61 rows)

test=#

Angenommen, es ist der 21. Mai:

Code:
test=# select * from turbokanne where datum >= case when date_part('day', '2017-05-21'::date) < 27 then (select (extract('year' from current_date-'1month'::interval)::text || '-' || extract('month' from current_date-'1month'::interval) || '-27')::date) else (select (extract('year' from current_date)::text || '-' || extract('month' from current_date) || '-01')::date) end; id  |  datum   
-----+------------
 117 | 2017-04-27
 118 | 2017-04-28
 119 | 2017-04-29
 120 | 2017-04-30
 121 | 2017-05-01
 122 | 2017-05-02
 123 | 2017-05-03
 124 | 2017-05-04
 125 | 2017-05-05
 126 | 2017-05-06
 127 | 2017-05-07
 128 | 2017-05-08
 129 | 2017-05-09
 130 | 2017-05-10
 131 | 2017-05-11
 132 | 2017-05-12
 133 | 2017-05-13
 134 | 2017-05-14
 135 | 2017-05-15
 136 | 2017-05-16
 137 | 2017-05-17
 138 | 2017-05-18
 139 | 2017-05-19
 140 | 2017-05-20
 141 | 2017-05-21
 142 | 2017-05-22
 143 | 2017-05-23
 144 | 2017-05-24
 145 | 2017-05-25
 146 | 2017-05-26
 147 | 2017-05-27
 148 | 2017-05-28
 149 | 2017-05-29
 150 | 2017-05-30
 151 | 2017-05-31
(35 rows)


Ich ändere jetzt das erst fixe Datum in current_date:

Code:
test=# select * from turbokanne where datum >= case when date_part('day', current_date) < 27 then (select (extract('year' from current_date-'1month'::interval)::text || '-' || extract('month' from current_date-'1month'::interval) || '-27')::date) else (select (extract('year' from current_date)::text || '-' || extract('month' from current_date) || '-01')::date) end;
 id  |  datum   
-----+------------
 121 | 2017-05-01
 122 | 2017-05-02
 123 | 2017-05-03
 124 | 2017-05-04
 125 | 2017-05-05
 126 | 2017-05-06
 127 | 2017-05-07
 128 | 2017-05-08
 129 | 2017-05-09
 130 | 2017-05-10
 131 | 2017-05-11
 132 | 2017-05-12
 133 | 2017-05-13
 134 | 2017-05-14
 135 | 2017-05-15
 136 | 2017-05-16
 137 | 2017-05-17
 138 | 2017-05-18
 139 | 2017-05-19
 140 | 2017-05-20
 141 | 2017-05-21
 142 | 2017-05-22
 143 | 2017-05-23
 144 | 2017-05-24
 145 | 2017-05-25
 146 | 2017-05-26
 147 | 2017-05-27
 148 | 2017-05-28
 149 | 2017-05-29
 150 | 2017-05-30
 151 | 2017-05-31
(31 rows)

test=#

Sollte sein, was Du suchst. Ob die MySQL-Datumsfunktionen das hergeben weiß ich aber nicht.
 
Code:
SELECT *
FROM daten
WHERE datum BETWEEN
    IF( DAY(NOY()) > 27
        , DATE(NOW() - INTERVAL 1 MONTH - DAY(NOW()) + INTERVAL 27 DAY)
        , DATE(NOW() - DAY(NOW()) + INTERVAL 27 DAY)
    )
AND
    NOW();

Hallo, danke für diesen Vorschlag. Bei Tagen im neuen Monat (also kleiner 27) bleibt das Ergebnis leer, d.h. es werden keine Treffer angezeigt.
Was ja diese Anfrage wäre: SELECT * FROM daten WHERE datum BETWEEN DATE (NOW() - DAY(NOW()) + INTERVAL 27 DAY) AND NOW()
 
Zuletzt bearbeitet von einem Moderator:
select * from turbokanne where datum >= case when date_part('day', current_date) < 27 then (select (extract('year' from current_date-'1month'::interval)::text || '-' || extract('month' from current_date-'1month'::interval) || '-27')::date) else (select (extract('year' from current_date)::text || '-' || extract('month' from current_date) || '-01')::date) end;

Sollte sein, was Du suchst. Ob die MySQL-Datumsfunktionen das hergeben weiß ich aber nicht.

Geht bei mir (und mySQL) leider nicht, ich bekomme bei der Anbrage 19 Fehler von PHPMyAdmin angezeigt:

Statische Analyse:

19 Fehler wurden während der Analyse gefunden.

  1. Unerkanntes Schlüsselwort. (near "case" at position 42)
  2. Unerkanntes Schlüsselwort. (near "when" at position 47)
  3. Unerwartetes Zeichen. (near "date_part" at position 52)
  4. Unerwartetes Zeichen. (near "(" at position 61)
  5. Unerwartetes Zeichen. (near "'day'" at position 62)
  6. Unerwartetes Zeichen. (near "," at position 67)
  7. Unerkanntes Schlüsselwort. (near "current_date" at position 69)
  8. Unerwartetes Zeichen. (near ")" at position 81)
  9. Unerwartetes Zeichen. (near "<" at position 83)
  10. Unerwartetes Zeichen. (near "27" at position 85)
  11. Unerkanntes Schlüsselwort. (near "then" at position 88)
  12. Unerwartetes Zeichen. (near "(" at position 93)
  13. Diese Art von Klausel wurde zuvor analysiert. (near "select" at position 94)
  14. Unerwartetes Zeichen. (near ")" at position 240)
  15. Unerkanntes Schlüsselwort. (near "else" at position 242)
  16. Unerwartetes Zeichen. (near "(" at position 247)
  17. Diese Art von Klausel wurde zuvor analysiert. (near "select" at position 248)
  18. Unerwartetes Zeichen. (near ")" at position 356)
  19. Unerkanntes Schlüsselwort. (near "end" at position 358)

Grüße
TurboKanne
 
Gibt es ggf eine Alternative, die auch bei mySQL funktioniert? Ich hatte noch eine Weile rumprobiert, konnte das Problem aber noch nicht lösen.
 
Das geht auf jedenfall ich bin jetzt aber mit der MySQL Syntax nicht vertraut. Ich frage mich aber warum ihr in einem WHERE mit IF arbeitet, AND und OR reichen doch vollkommen aus.
 
Das geht auf jedenfall ich bin jetzt aber mit der MySQL Syntax nicht vertraut. Ich frage mich aber warum ihr in einem WHERE mit IF arbeitet, AND und OR reichen doch vollkommen aus.

Hallo Ukulele,

schau dir diese Anforderung einmal an:

Plastischer - ein paar Beispiele

Heute ist 29.Mai - Abfrage soll Daten ausgeben zwischen 27.Mai und heute
Heute ist 01.Juni - Abfrage soll Daten ausgeben zwischen 27.Mai und heute
Heute ist 19.Mai - Abfrage soll Daten ausgeben zwischen 27.April und heute
Heute ist 22.Januar 2017 - Abfrage soll Daten ausgeben zwischen 27.Dezember 2016 und heute


Ich finde da keine Möglichkeit dies nur mit AND oder OR zu realisieren. Kannst mir ja gerne mal einen Tipp geben, egal ob das SQL stimmig ist oder nicht.

Gruss

Bernd
 
Werbung:
Er wiederspricht sich auch etwas in seinen Anforderungen.
Post #1:
Heute ist 29.Mai - Abfrage soll Daten ausgeben zwischen 27.Mai und heute.
= 27. Mai bis X. Mai
Post #2:
Nach dem 27. sollen die Daten das aktuellen Monats abgefragt werden.
= 1. Mai bis X. Mai = alles aus Mai

Beides läßt sich aber abbilden, ich vermute er will immer den letzen 28. bis Heute abbilden (hier mal MSSQL):
Code:
DECLARE   @heute DATE
SET     @heute = '2017-04-20'

SELECT   *
FROM   tabelle
WHERE   datepart(day,@heute) > 27
AND     datum BETWEEN dateadd(day,27,dateadd(month,datediff(month,0,@heute),0)) AND @heute
OR     datepart(day,@heute) <= 27
AND     datum BETWEEN dateadd(day,27,dateadd(month,-1,dateadd(month,datediff(month,0,@heute),0))) AND @heute
ORDER BY datum
Dabei ist @heute natürlich nur eine Variable zum testen und kann mit der Funktion für DatumHeute ersetzt werden. Außerdem kann das BETWEEN weg fallen wenn es sowieso keine Daten über Heute hinaus gibt und dateadd(month,datediff(month,0,@heute),0) ist nur die Bestimmung des 1. des Monats von @heute, das ist sicherlich Server spezifisch. Man könnte also grob sagen:
Code:
SELECT   *
FROM   tabelle
WHERE   datepart(day,@heute) > 27
AND     datum > dateadd(day,27,@MonatsErsterHeute)
OR     datepart(day,@heute) <= 27
AND     datum > dateadd(day,27,@MonatsErsterHeute) - 1
ORDER BY datum
IF ist einem OR gewichen.
 
Zurück
Oben