1. Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm
    Information ausblenden

Oracle - Geburtstage in den nächsten 30 Tagen

Dieses Thema im Forum "Oracle" wurde erstellt von marja, 3 Februar 2020.

  1. marja

    marja Neuer Benutzer

    Hallo zusammen,

    ich möchte gerne mit vorhandenen Daten abfragen, welche Geburtstage demnächst anstehen.
    Hierfür habe ich eine Tabelle mit den Usern und den Geburtstagen.

    Nun möchte ich gerne eine View erstellen in der mir die User angezeigt werden die von heute bis in den nächsten 30 Tagen (also demnächst) Geburtstag haben. Der Geburtstag ist ja bsp. 01.01.1978 abgespeichert. Um zu vergleichen müsste ich doch erst das vorhandene Geburtstag EXTRACT nach Tag, Monat plus aktuelles Jahr und dann mit BETWEEN zwischen dem heutigen Tag (SYSDATE) und dem Tag in 30 Tagen vergleichen?

    Wie aber kann ich am beste dieses Geburtstdatum zusammenbauen oder kann ich auch das Datum vergleichen ohne die Jahreszahl?

    Dank Marja
     
  2. akretschmer

    akretschmer Datenbank-Guru

    Lösung für PostgreSQL, könnte evtl. auch direkt in Oracle gehen:

    Code:
    test=*# select * from marja ;
     person |    geb     
    --------+------------
          1 | 1966-08-30
          2 | 1977-02-16
          3 | 2007-03-10
    (3 rows)
    
    test=*# select * from marja where extract(year from age( geb, current_date)) != extract(year from age( geb, current_date + 3));
     person | geb
    --------+-----
    (0 rows)
    
    test=*# select * from marja where extract(year from age( geb, current_date)) != extract(year from age( geb, current_date + 30));
     person |    geb     
    --------+------------
          2 | 1977-02-16
    (1 row)
    
    test=*# select * from marja where extract(year from age( geb, current_date)) != extract(year from age( geb, current_date + 60));
     person |    geb     
    --------+------------
          2 | 1977-02-16
          3 | 2007-03-10
    (2 rows)
    
     
  3. dabadepdu

    dabadepdu Fleissiger Benutzer

    In Oracle kann man sehr schön mit DATE Spalten rechnen. Das hilft hier allerdings nicht so.
    Man muss die Jahre loswerden, die in den Geburtstagdatumswerten stecken. Dazu eignet sich schlicht eine Formatierung nach MonatTag MMDD und dieses Verfahren dürfte dann sogar in nahezu jedem Datenbanksystem funktionieren. (Natürlich unterscheiden sich die Datums-Funktionen )

    Code:
    -- die Geburtstage der nächsten 30 Tage
    -- mit bdate = Spalte mit Geburtsdatum
    -- und birthdatetable = verwendete Tabelle
    -- die select clause dient nur der Anschauung
    -- die where clause reicht.
    select bdate,                          
           to_char(bdate,   'mmdd') as bday,
           to_char(sysdate, 'mmdd') as today,
           to_char(bdate,   'mmdd') - to_char(sysdate, 'mmdd') as daysBetween
      from birthdateTable  
     where to_char(bdate,   'mmdd') -
           to_char(sysdate, 'mmdd') between 0 and 30
    
     
  4. akretschmer

    akretschmer Datenbank-Guru

    Bist Du Dir da sicher?

    Code:
    test=*# select to_char('2020-03-01'::date,'mmdd')::int - to_char(current_date, 'mmdd')::int;
     ?column?
    ----------
           91
    (1 row)
    
    to_char() liefert das, was der Name suggeriert, und damit ist schon mal schlecht rechnen. Und dann ist 'mmdd' im 'dd' - Teil ja auch auf max. 31 begrenzt. Mir kommt das komisch vor ...
     
  5. dabadepdu

    dabadepdu Fleissiger Benutzer

    oh mann wie peinlich!

    Also die Formatmaske ist Schrott, es muss "DDD" sein.



    Code:
    ..where 
    to_char(bdate,'DDD')-
    to_char(current_date, 'DDD') between 0 and 30
    
     
    akretschmer gefällt das.
  6. akretschmer

    akretschmer Datenbank-Guru

    das gibt aber noch mal Ärger wenn es über das Jahr geht, oder? Frag ja nur ...
     
    Walter gefällt das.
  7. dabadepdu

    dabadepdu Fleissiger Benutzer

    Ja, Du hast Recht.
     
  8. castorp

    castorp Datenbank-Guru

    Der Ausdruck "to_char(bdate,'DDD') - to_char(current_date, 'DDD')" wird überhaupt nicht funktionieren, da man nicht einen String von einem anderen abziehen kann. Man muss den String den man darüber erhält, wieder in ein richtiges Datum umwandeln, sonst kann man damit nicht rechnen.

    Ich würde das so machen:
    Code:
    with bdays as (
      select name, bday,
             case
               when to_char(sysdate, 'mmdd') <= to_char(bday, 'mmdd')
                  then to_date(to_char(extract(year from sysdate), 'FM0000')||to_char(bday, 'mmdd'), 'yyyymmdd')
               else
                 to_date(to_char(extract(year from sysdate) + 1, 'FM0000')||to_char(bday, 'mmdd'), 'yyyymmdd')
             end as next_bday
      from the_table
    )
    select *
    from bdays
    where next_bday <= sysdate + 30
    Die CTE liefert alle Einträge der Tabelle und berechnet für jeden, wann der nächste Geburtstag ansteht.

    Der CASE Ausdruck prüft ob der Geburtstag dieses Jahr schon war, dann ist erst nächstes Jahr wieder einer fällig. Wenn nicht, dann eben dieses Jahr. Im äußeren SELECT wird dann nur noch abgeprüft ob in den nächsten 30 Tagen einer ansteht.

    Online Beispiel
     
    Walter gefällt das.
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden