Wiek z peselu - ORACLE

0

Witam! Mam w Oraclu tabelę klientów w ktorych zawarty jest ich pesel. Potrzebuję w selekcie wyciągnąć z tego wiek. Czy ktoś zna jakieś funkcjonalne rozwiazanie?
Po pierwsze czy jest jakas funkcja zwracająca roznicę w datach? SYSDATE-daraurodzenia da mi niezbyt użyteczny wynik w dniach.
Po drugie co z 'nowymi' peselami?

Pozdrawiam

0

Standardowo wiek moze wyciągnąć np poprzez

 select PESEL,
  trunc( months_between( SYSDATE, TO_DATE(substr(pesel,1,6),'yymmdd') ) /12 )  as wiek
 FROM DIM_KLIENT ;
 

jednak z winy formatu zwraca to liczbę ujemną, jak to sensownie zmodyfikować?

0

A co ma być z nowymi Peselami? Stulecie kodowane jest na znakach przeznaczonych także na miesiąc. Na wiki masz wszystko http://pl.wikipedia.org/wiki/PESEL
Pamiętaj też że są przypadki wyjątkowe, gdzie "data" z pesel nie jest zgodna z datą ur. człowieka. Mamy w firmie nawet specjalną tablicę do obsługi takich wyjątków.
Założenia twórców Pesel były ok, tylko potem przyszli inteligentni inaczej urzędnicy i wyszło jak zawsze :)

0

zwraca liczbę ujemną bo yy rozpoznaje jako 20yy a nie 19yy
czyli np. dla peselu 800101 zwrócona data przez to_date to 2080.01.01 a nie 1980.01.01

0

Wiem dlaczego zwraca;) Nie znam oracla więc przyznam że ciężko mi się w nim pisze. Mysle o czyms takim (na razie niedzialającym).
W zaleznosci od miesiaca dodaje tekstowo 18,19 lub 20 (pomijam na razie inne)


select PESEL,
trunc( months_between( SYSDATE, TO_DATE(substr(pesel,1,6),'yymmdd') ) /12 )  as wiek,
to_number(substr(pesel,1,2), '99') as rok, 
to_number(substr(pesel,3,2), '99') as miesiac, 
to_number(substr(pesel,5,2), '99') as dzien, 

CASE 

WHEN to_number(substr(pesel,3,2), '99') BETWEEN 01 AND 12 
THEN 

trunc( months_between( to_date(SYSDATE,'YYYYMMDD'), TO_DATE(
'19'||substr(pesel,1,2), '99') ||to_number(substr(pesel,3,2)||substr(pesel,5,2)
,'yyyymmdd') ) /12 )

WHEN to_number(substr(pesel,3,2), '99') BETWEEN 81 AND 92 
THEN 

trunc( months_between(  to_date(SYSDATE,'YYYYMMDD'), TO_DATE(
'18'||substr(pesel,1,2), '99') ||to_number(substr(pesel,3,2)-80||substr(pesel,5,2)
,'yyyymmdd') ) /12 )

WHEN to_number(substr(pesel,3,2), '99') BETWEEN 21 AND 32 
THEN

trunc( months_between(   to_date(SYSDATE,'YYYYMMDD'), TO_DATE(
'20'||substr(pesel,1,2), '99') ||to_number(substr(pesel,3,2)-20||substr(pesel,5,2)
,'yyyymmdd') ) /12 )

ELSE 'taki pesel nie mogl zostac nadany'
END ) wiek
    FROM KLIENT ;
    
    END
0

Data z PESEL

to_date(
case floor(to_number(substr(pesel,3,2),'yymmdd'))/20) 
  when 4 then '18'
  when 0 then '19'
  when 1 then '20'
  when 2 then '21'
  when 3 then '22'
end || substr(pesel,1,2)
|| mod(to_number(substr(pesel,3,2), 20)
|| substr(pesel,5,2)
,'yyyymmdd')
0

select X, personalcode, add_months(to_date(substr(personalcode,1,6),'yymmdd'),-12100),
trunc(months_between(X, add_months(to_date(substr(personalcode,1,6),'yymmdd'),-12
100))/12)
from Z;

1 użytkowników online, w tym zalogowanych: 0, gości: 1