In einem kürzlich durchgeführten Projekt musste angegeben werden, wann eine Ressource vollständig verbraucht ist. Neben dem Datum des Erschöpfungskalenders wurde ich gebeten, die verbleibende Zeit im englischen Format anzuzeigen, etwa "1 Jahr, noch 3 Monate".
Die eingebaute DATEDIFF
Funktion
Gibt die Anzahl ... der angegebenen Datumsgrenzen zurück, die zwischen dem angegebenen Start- und Enddatum überschritten wurden.
Bei unverändertem Gebrauch kann dies zu irreführenden oder verwirrenden Ergebnissen führen. Wenn Sie beispielsweise ein Intervall von JAHR verwenden, werden 1999-12-31 (JJJJ-MM-TT) und 2000-01-01 ein Jahr voneinander entfernt sein, während der gesunde Menschenverstand sagen würde, dass diese Daten nur um einen Tag voneinander getrennt sind. Umgekehrt wird die Verwendung eines Intervalls von TAG 1999-12-31 und 2010-12-31 durch 4.018 Tage getrennt, während die meisten Menschen "11 Jahre" als bessere Beschreibung ansehen würden.
Ausgehend von der Anzahl der Tage und der Berechnung von Monaten und Jahren wäre es anfällig, Fehler in Jahr und Monatsgröße zu überspringen.
Ich habe mich gefragt, wie dies in den verschiedenen SQL-Dialekten implementiert werden kann. Beispielausgabe umfasst:
create table TestData(
FromDate date not null,
ToDate date not null,
ExpectedResult varchar(100) not null); -- exact formatting is unimportant
insert TestData (FromDate, ToDate, ExpectedResult)
values ('1999-12-31', '1999-12-31', '0 days'),
('1999-12-31', '2000-01-01', '1 day'),
('2000-01-01', '2000-02-01', '1 month'),
('2000-02-01', '2000-03-01', '1 month'), -- month length not important
('2000-01-28', '2000-02-29', '1 month, 1 day'), -- leap years to be accounted for
('2000-01-01', '2000-12-31', '11 months, 30 days'),
('2000-02-28', '2000-03-01', '2 days'),
('2001-02-28', '2001-03-01', '1 day'), -- not a leap year
('2000-01-01', '2001-01-01', '1 year'),
('2000-01-01', '2011-01-01', '11 years'),
('9999-12-30', '9999-12-31', '1 day'), -- catch overflow in date calculations
('1900-01-01', '9999-12-31', '8099 years 11 months 30 days'); -- min(date) to max(date)
Ich verwende zufällig SQL Server 2008R2, bin aber interessiert zu erfahren, wie andere Dialekte damit umgehen würden.