Datumbereich monats- und tagabhängig selektieren

Ludwigmller

SQL-Guru
Beiträge
171
Ich habe ein View, das für mehrer Jahre pro Tag ein Datensatz ausgibt. Es gibt eine Spalte saison, die die Saison enthält, da diese vom 1.10. bis 30.9. geht.
Ich möchte nun alle Zeilen selektieren, die vor einem p_monat und p_tag liegen. p_monat und p_tag sind Parameter der Funktion.

Bsp.: p_monat = 3, p_tag =15
für jede Saison sollen nur die Zeilen ausgegeben werden, die im Datumsbereich 1.10.YYYY bis 15.3.(YYYY+1) liegen.

p_monat =12, tag=1
für jede Saison sollen nur die Zeilen ausgegeben werden, die im Datumsbereich 1.10.YYYY bis 1.12.YYYY liegen.


Wie mache ich das am besten?
 
Werbung:
Mein Versuch:
SQL:
WHERE
    datum < concat(extract(YEAR FROM datum),'-',p_monat,'-',p_tag)::date
    AND datum > concat(extract(YEAR FROM datum)-1,'-',10,'-',1)::date
 
Ich bin kein Fan davon Datumswerte via Strings zu erzeugen, deswegen würde ich es wohl so machen:
Code:
where datum > make_date(extract(year from datum)::int, 10, 1)
   and datum < case 
                 when p_monat <= 12 then make_date(extract(year from datum)::int, p_monat, p_tag)
                 else make_date(extract(year from datum)::int + 1, p_monat, p_tag)
               end
 
Bei deiner Antwort wird else nie erreicht.
Hier ein Versuch von mir, funktioniert aber noch nicht:
SQL:
datum > make_date((extract(year from datum))::int, 10, 1)
           and datum < case
                     when p_monat >=9 then make_date(extract(year from datum)::int, p_monat, 15)
                     -- p_monat <=9
                     else
                         case
                            when extract(month from datum) <=9 then make_date((extract(year from datum)+1)::int, p_monat, p_tag)
                            -- month(datum) >9
                            else make_date(extract(year from datum)::int, p_monat, p_tag)
                        end       
                   end
 
Zuletzt bearbeitet:
Bei deiner Antwort wird elsenie erreicht.
Stimmt, war wohl noch ein Kaffee zu wenig ;)

Allerdings ist das = in <= 9 auch überflüssig. Da bei = 9 ja schon der erste Zweig verwendet wird.

Ich glaube man könnte es etwas einfacher so schreiben:
Code:
   and datum < case 
                 when p_monat in (10,11,12) then make_date(extract(year from datum)::int, p_monat, p_tag)
                 else make_date(extract(year from datum)::int + 1, p_monat, p_tag)
               end
 
Muss man nicht auch den Monat von datum unterscheiden ?
Bei deinem letzten Code, würde eine Zeile mit datum = 2023-02-01 und p_monat =12 ein Datumsbereich vom 2023-10-01 bis 2023-12-15 erzeugen, statt 2022-10-15 bis 2022-12-15. Aber das Ergebnis, die Zeile wird ausgeschlossen, ist richtig.
Bei datum=2023-02-01 und p_monat=2 wird ein Datumsbereich vom 2023-10-01 bis 2024-02-15 erzeugt. Hier wird die Zeile rausgefiltert, obwohl sie eigentlich dabei sein sollte
 
Werbung:
so scheint es zu funktionieren. oder geht es einfacher?
SQL:
datum > case
                    when extract(month from datum) >9 then make_date((extract(year from datum))::int, 10, 1)
                    -- Monat(datum) <= 9
                    else make_date(((extract(year from datum))-1)::int, 10, 1)
                end    
           and datum < case
                     when extract(month from datum) >9 then case
                                                when p_monat >9 then make_date(extract(year from datum)::int, p_monat, p_tag)
                                                else make_date((extract(year from datum) + 1)::int, p_monat, p_tag)
                                            end
                    -- p_monat <=9
                    else case
                                when p_monat >9 then make_date((extract(year from datum) - 1)::int, p_monat, p_tag)
                                else make_date(extract(year from datum)::int, p_monat, p_tag)
                            end
                    end
Im Anhang die Logik dahinter.
 

Anhänge

  • 1679045047912.png
    1679045047912.png
    28,8 KB · Aufrufe: 2
Zuletzt bearbeitet:
Zurück
Oben