生日不是从出生日期算起的公式。这是一年中的固定日期,闰年除外。使用该逻辑,您可以使用以下查询计算今年的生日:
with date_of_birth as
(SELECT TO_DATE('01-NOV-1971','DD-MON-YYYY') as dt FROM DUAL
UNION
SELECT TO_DATE('29-FEB-2004','DD-MON-YYYY')FROM DUAL
)
SELECT
dt as date_of_birth
,CASE
WHEN TO_CHAR(dt,'DD-MON') = '29-FEB' THEN
TO_DATE('01-MAR-'||EXTRACT(year FROM sysdate),'DD-MON-YYYY')
ELSE
TO_DATE(TO_CHAR(dt,'DD-MON-')||EXTRACT(year FROM sysdate),'DD-MON-YYYY')
END AS this_year_birthday
FROM date_of_birth;
它会返回
DATE_OF_BIR THIS_YEAR_B
----------- -----------
01-NOV-1971 01-NOV-2019
29-FEB-2004 01-MAR-2019
--已编辑。正如 Jeffrey 指出的,如果在闰年运行,上述查询会返回错误的结果。这是一个更新版本,允许用户在今年以外的时间运行它。将返回与 Jeffrey Kemps 的答案相同的结果,但从另一个角度来看。
with
FUNCTION is_valid_date (date_str_i VARCHAR2, format_i VARCHAR2) RETURN VARCHAR2
/* check if date is valid */
AS
l_dummy_dt DATE;
date_not_valid_for_m EXCEPTION;
PRAGMA EXCEPTION_INIT(date_not_valid_for_m, -01839);
BEGIN
SELECT TO_DATE(date_str_i,format_i) INTO l_dummy_dt FROM DUAL;
RETURN 'Y';
EXCEPTION WHEN date_not_valid_for_m THEN
RETURN 'N';
END;
date_of_birth as
(SELECT TO_DATE('01-NOV-1971','DD-MON-YYYY') as dt FROM DUAL
UNION
SELECT TO_DATE('29-FEB-2004','DD-MON-YYYY')FROM DUAL
),
year_to_check as
(SELECT '2016' as yr FROM DUAL)
SELECT
dt as date_of_birth
,CASE
WHEN TO_CHAR(dt,'DD-MON') = '29-FEB' THEN
CASE
WHEN is_valid_date(date_str_i => '29-FEB-'||yr,format_i => 'DD-MON-YYYY') = 'N'
THEN TO_DATE('01-MAR-'||yr,'DD-MON-YYYY')
ELSE
TO_DATE(TO_CHAR(dt,'DD-MON-')||yr,'DD-MON-YYYY')
END
ELSE
TO_DATE(TO_CHAR(dt,'DD-MON-')||yr,'DD-MON-YYYY')
END AS this_year_birthday
FROM date_of_birth, year_to_check;
/