Дата рождения текущего года с использованием oracle sql

Пытаюсь получить дату рождения в текущем году. Например, если DOB = 19800925, день рождения в текущем году - 20180925. (примечание: мы не должны просто заменять год из-за DOB високосного года (например: 20000229))

with tmp_dob as 
(
    select '19900101' Birthday from dual union all
    select '19901231' Birthday from dual union all
    select '20040229' Birthday from dual union all
    select '20041231' Birthday from dual union all
    select '20171231' Birthday from dual union all
    select '20051231' Birthday from dual 
)
select Birthday,add_months(to_date(Birthday,'YYYYMMDD'),(trunc(months_between(sysdate ,to_date(Birthday,'YYYYMMDD'))/12)) * 12) current_year_dob 
from tmp_dob;

🤔 А знаете ли вы, что...
Основными операциями SQL являются SELECT (выборка данных), INSERT (вставка данных), UPDATE (обновление данных) и DELETE (удаление данных).


1
512
3

Ответы:

Решено

Эта логика должна работать:

with tmp_dob as (
      select to_date('19900101', 'YYYYMMDD') as Birthday from dual union all
      select to_date('19901231', 'YYYYMMDD') Birthday from dual union all
      select to_date('20040229', 'YYYYMMDD') Birthday from dual union all
      select to_date('20041231', 'YYYYMMDD') Birthday from dual union all
      select to_date('20171231', 'YYYYMMDD') Birthday from dual union all
      select to_date('20051231', 'YYYYMMDD') Birthday from dual 
    )
select Birthday,
       add_months(birthday, 12 * (extract(year from sysdate) - extract(year from birthday)))
from tmp_dob;

Я думал об использовании струнного подхода, поскольку дни рождения, которые вы используете, тоже связаны со струнами. Я использую синтаксис BigQuery, но в каждом SQL должны быть похожие функции.

with tmp_dob as
(
    select '19900101' Birthday from dual union all
    select '19901231' Birthday from dual union all
    select '20040229' Birthday from dual union all
    select '20041231' Birthday from dual union all
    select '20171231' Birthday from dual union all
    select '20051231' Birthday from dual 
)
select Birthday,
  CASE WHEN MOD(CAST(SUBSTR(Birthday,1,4) AS INT64), 4) = 0 AND SUBSTR(Birthday,5,8) = '0229'
       THEN CONCAT(CAST(EXTRACT(YEAR FROM CURRENT_DATE) AS STRING), '0228')
       ELSE CONCAT(CAST(EXTRACT(YEAR FROM CURRENT_DATE) AS STRING), SUBSTR(Birthday,5,8)) END AS bd
from tmp_dob;

Подход добавления месяцев работает, но вы получите 2/28 для дней рождения високосного дня. Если вы хотите, чтобы это было 03/01 или было настраиваемым, используйте регистр для обнаружения условия и отмены:

with tmp_dob as (
      select to_date('19900101', 'YYYYMMDD') as Birthday from dual union all
      select to_date('19901231', 'YYYYMMDD') Birthday from dual union all
      select to_date('20040229', 'YYYYMMDD') Birthday from dual union all
      select to_date('20041231', 'YYYYMMDD') Birthday from dual union all
      select to_date('20171231', 'YYYYMMDD') Birthday from dual union all
      select to_date('20051231', 'YYYYMMDD') Birthday from dual 
    )
select Birthday,
       case 
         when 
             to_date(extract(year from sysdate) || '1231', 'YYYYMMDD') -
                 to_date(extract(year from sysdate) || '0101', 'YYYYMMDD') < 365
             and to_char(birthday, 'MMDD') = '0229' then
                 to_date(extract(year from sysdate) || '0301', 'YYYYMMDD')
         else  
                 add_months(birthday, 12 * (extract(year from sysdate) - extract(year from birthday)))
         end as bd_this_year
from tmp_dob;

Результаты:

BIRTHDAY    BD_THIS_YEAR
1/1/1990    1/1/2018
12/31/1990  12/31/2018
2/29/2004   3/1/2018
12/31/2004  12/31/2018
12/31/2017  12/31/2018
12/31/2005  12/31/2018

Подумайте о том, чтобы функция выполняла то же самое - ваш запрос будет легче читать.