SQL Anzahl Tage zwischen zwei Dates innerhalb Monat xy

amasingh

Ensign
Registriert
Dez. 2012
Beiträge
215
Hallo zusammen,

ich stehe gerade auf dem Schlauch.

Ich muss aus einer Tabelle mit Urlaubseinträgen die Anzahl von Urlaubstagen für Person xy in Monat yz rausfinden.
In der Tabelle ist das start sowie das Enddatum eingetragen, wobei beides nicht im gleichen Monat liegen muss und genau hier liegt mein Problem. Einfach nur "DATE_DIFF" geht hier also nicht.

Beispiel:
user, urlaub_start, urlaub_ende
1, 17.01.2015, 05.02.2015
1, 18.02.2015, 10.03.2015

Nun möchte ich die Anzahl der Urlaubstage im Jahr 2015 aus Monat Februar haben. Das wären hier:
01.02.2015 bis 05.02.2015 = 5
18.02.2015 bis 28.02.2015 = 10

-> insgesamt 15 Urlaubstage in diesem Monat.


Ein Ansatz von mir wäre zB die Tage, für die es keinen Eintrag gibt, zu zählen und von der Anzahl der Tage, des Monats abzuziehen, doch wie setzt man das am besten um?
 
Zuletzt bearbeitet:
Wie wäre es hier mit ?
Weiß nicht in wieweit dir das jetze hilft, hatte damit länger nix mehr zu tuen.
 
Danke, aber was sub-selects sind, weiß ich, das hilft mir leider nicht weiter ;)
 
Tut mir leid, habe selbst auch noch bisschen weitergeguckt, aber nix gutes gefunden.
Schon komisch ist ja nicht so als wenn es da problem erst seit gestern gibt .
 
Mein Ansatz wäre: Zuerst vergleichen, ob Start und Ende im gleichen Monat, wenn nicht, dann teile den Eintrag am Ende des ersten = Beginn des nächsten Monats auf.

Beispiel:
user, urlaub_start, urlaub_ende
1, 17.01.2015, 05.02.2015

Du zählst die Tage vom 17.01. bis 31.01. und für Februar vom 01.02. bis 05.02.

Das ganze funktioniert natürlich nicht mit einem Befehl, aber mit sub-selects kein Problem.
 
Bei Postgresql wäre das so möglich

SELECT COUNT(anzahl.tag) FROM
(
SELECT tage.tag, testdate.* FROM
(SELECT tag FROM generate_series(
(SELECT min(date_start) FROM testdate),
(SELECT max(date_ende) FROM testdate),
'1 day'::interval) tag
) tage
JOIN testdate
ON (date_start,date_ende) OVERLAPS (tage.tag,tage.tag+'1 day'::interval)
ORDER BY 1
) anzahl
WHERE EXTRACT(MONTH FROM anzahl.tag) = 2; -- Monat 1=Januar bis 12=Dezember
 
Jetzt habe ich mich gerade gefreut, dass ich die Lösung habe.. Da kommt "Astrein" und versaut es ;)

Meine Lösung war jedenfalls wesentlich leichter, als gedacht. Logisch formuliert:
(ANZAHL TAGE MONAT) - ( ( MAXIMUM VON 0 UND ANFANGSDATUM - ERSTER TAG DES MONATS ) + ( MAXIMUM VON 0 UND LETZTER TAG DES MONATS - ENDDATEUM)) = Anzahl Urlaubstage des Monats.

Beispiel:
ANZAHL TAGE MONAT = 28 // Anzahl Tage um Februar
MAXIMUM VON 0 UND (17.01.2015 - 01.02.2015) = 0 // 0 ist größer als minus XX Tage
MAXIMUM VON 0 UND (28.02.2015 - 15.02.2015) = 13 // Differenz zwischen den zwei Dates ist 13

Ergibt genau 15 Tage

Das ganze funktioniert ohne Sub Selects nur mit Plus und Minus rechnerei ;)
 
Zuletzt bearbeitet:
Also die Wochentage könnte man so abfangen, wenn man bei meiner oben geposteten Abfrage, einfach die WHERE Bedingung um folgende ergänzen

AND EXTRACT(dow FROM anzahl.tag) BETWEEN 1 AND 5
-- mit select EXTRACT(dow FROM current_date), to_char(current_date,'Day') prüfen welche Nummer welcher Wochentag ist
 
Dazu einfach eine Tabelle mit den entsprechden Feiertagen anlegen und über eine weitere Where-Bedingung prüfen ob das Datum nicht in dieser vorkommt, wenn nicht vorhanden zählen.

AND anzahl.tag NOT IN (SELECT feiertag FROM feiertage)
 
Zurück
Oben