2017-09-07 1 views
1

Ich versuche, eine Liste von Personen basierend auf ihrem Alter zu replizieren, mit H2 DB.H2 Database - DATEDIFF funktioniert nicht richtig

Ich bin mit dieser Abfrage:

DATEDIFF('YEAR', BIRTHDATE, CURRENT_DATE) 

Wenn jedoch die BIRTH Oct-24-1981 ist, H2 liefert 36, und es sollte 35 sein Diese Person 36 im Oktober-24 drehen wird, Es scheint also so zu sein, dass H2 nur das tatsächliche Jahr vom Geburtsjahr abzieht (2017-1981 = 36), und das stimmt nicht.

Ich weiß, ich könnte dies mit Java lösen, aber es würde eine Menge zusätzlicher Verarbeitung benötigen. Benutzer müssen aus der Datenbank nach allen Personen eines bestimmten Alters suchen. Ich benutze H2 Version 1.4.195

Jede Hilfe wird geschätzt werden !!

Antwort

2

können Sie versuchen, mit:

select cast(DATEDIFF(dd,'09-20-1981','09-17-2017')/365.25 as int) 

dem Sie das Alter auf der Anzahl von Monaten statt Jahren basiert erhalten - denn er ist nicht 36 noch.

+0

das ist eigentlich genauer, aber immer noch, wenn das Geburtsdatum ist Sept-20-1981, H2 wird zurückkehren 36 (wenn diese Person am 20. September 36 wird) – Sergio

+0

Ich könnte stattdessen Tage verwenden, aber immer noch wird es aufgrund von Schaltjahren nicht 100% genau sein. Mit MySQL funktioniert diese Funktion perfekt, aber für dieses Projekt muss ich H2 verwenden – Sergio

+0

versuchen Sie die aktualisierte Abfrage – kazzi

1

auf der Grundlage Ihrer Idee kam ich mit diesem nach oben, die tatsächlich funktioniert:

FLOOR(DATEDIFF(dd, BIRTHDATE, CURRENT_DATE)/365.25) 

Es ist nicht sauber, aber es funktioniert. Vielleicht in zukünftigen Versionen von H2 wird dies nicht notwendig sein.

+0

Dies wird immer noch falsche Ergebnisse an Geburtstagen und für historische geben Daten, zum Beispiel "1800-09-20", "1901-09-21". Du hast Glück, dass 2000 sich um 400 teilt und ein Schaltjahr war, so dass die Lebenden nur an Geburtstagen betroffen sind. Ich habe eine alternative Lösung veröffentlicht. – Oleg

1

Sie können eine benutzerdefinierte Funktion erstellen:

CREATE ALIAS AGE AS ' 
    long calculateAge(java.sql.Date birthDate, java.sql.Date currentDate) { 
     if ((birthDate != null) && (currentDate != null)) { 
      return java.time.temporal.ChronoUnit.YEARS.between(birthDate.toLocalDate(), currentDate.toLocalDate()); 
     } else { 
      return 0; 
     } 
    } 
'; 

Und dann benutzen Sie einfach es select age('2001-09-20', now());