Пытаюсь получить дату рождения в текущем году. Например, если 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 (удаление данных).
Эта логика должна работать:
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
Подумайте о том, чтобы функция выполняла то же самое - ваш запрос будет легче читать.