大家好,我沒有代碼在這裏顯示,因爲我無法用乾淨的方式來包裝我的頭。在我們的表格中,我有一個生日專欄,它是一個時間戳。我需要找到在未來3個月內生日的所有人。甲骨文 - 生日日期數學
所以我知道我可以添加3個月的sysdate,但我怎麼做日期比較,而忽略了一年我有一個循環引發。
大家好,我沒有代碼在這裏顯示,因爲我無法用乾淨的方式來包裝我的頭。在我們的表格中,我有一個生日專欄,它是一個時間戳。我需要找到在未來3個月內生日的所有人。甲骨文 - 生日日期數學
所以我知道我可以添加3個月的sysdate,但我怎麼做日期比較,而忽略了一年我有一個循環引發。
挑戰是從現在開始到下一個生日間隔的月數。 MONTHS_BETWEEN()
函數加上除以12得到的結果讓我們接近,但我們必須處理小數灰塵並將餘數轉換爲有用的東西。我可以想出兩種方法來處理這個問題:MOD()
和CEIL()
。
使用CEIL
我們將計算下一個生日和當前年齡之間的差異,並在謂詞中使用它。在這種情況下,結果是十進制年,所以我們需要比較四分之一年(3/12):
where (ceil(months_between(sysdate, b.birthday)/12) -
months_between(sysdate, b.birthday)/12) <= 3/12;
這是一個有點笨重。另外,MOD
會給我們的幾個月去的剩餘部分,所以從12減去MOD
給了我們幾個月向左走:
where (12 - mod(months_between(sysdate, b.birthday),12)) <= 3;
這是在行動與樣本數據:
with b as
(select date '1990-05-10' birthday from dual union all
select date '1970-09-23' from dual union all
select date '2000-04-02' from dual union all
select date '1948-11-12' from dual)
select
b.birthday,
months_between(sysdate, b.birthday) months,
months_between(sysdate, b.birthday)/12 years,
ceil(months_between(sysdate, b.birthday)/12) age_to_be,
ceil(months_between(sysdate, b.birthday)/12) - months_between(sysdate, b.birthday)/12 period_to_birthday,
mod(months_between(sysdate, b.birthday),12) mod_months,
12 - mod(months_between(sysdate, b.birthday),12) months_diff
from b
where (12 - mod(months_between(sysdate, b.birthday),12)) <= 3;
-- Or
--where (ceil(months_between(sysdate, b.birthday)/12) -
-- months_between(sysdate, b.birthday)/12) <= 3/12;
編輯:我會留下我舊的和不正確的答案在這裏作爲參考,我會看看另一種方式。
只需使用ADD_MONTHS()
和LAST_DAY()
查找生日在計算值內的所有行。無需擔心年份組件,您不使用字符串文字。
這個例子蒙上sysdate
爲timestamp
,則得到當月的最後一天,並增加了三個月,即:
select add_months(last_day(cast(sysdate as timestamp)),3) from dual;
因此,使用這種邏輯,你可以:
select *
from your_table
where birthday <= add_months(last_day(cast(sysdate as timestamp)),3);
或者只是:
select *
from your_table
where birthday <= add_months(last_day(sysdate),3);
Oracle很好地處理數據類型轉換rsion爲你。
由於年底包裝,邏輯有點複雜。但是,這應該工作:
where (extract(month from sysdate) < 10 and
to_char(birthday, 'MM-DD') between to_char(sysdate, 'MM-DD') and
to_char(add_month(sysdate, 3), 'MM-DD')
) or
(extract(month from sysdate) >= 10 and
(to_char(birthday, 'MM-DD') >= to_char(sysdate, 'MM-DD') or
to_char(birthday, 'MM-DD') <= to_char(add_month(sysdate, 3), 'MM-DD')
)
);
一個人的生日(紀念日)在本年度,因爲他們的出生日期是:
TRUNC(SYSDATE,'Y') + (dob - TRUNC(dob,'Y'))
如果你可以告訴這是未來三個月的東西之內像:
SELECT 'Yes' FROM dual
WHERE TRUNC(SYSDATE,'Y') + (dob - TRUNC(dob,'Y'))
BETWEEN SYSDATE AND ADD_MONTHS(SYSDATE,3);
只有一個小問題,那就是如果一個人出生於閏年12月31日,這種方法有一個外情況的一個錯誤,當你在一個非閏年運行年(即它在未來三個月內不會將該人確定爲開始,直到10月1日)。
這使得OP在談論出生日期的假設 - 而我很確定他們是指生日,即某人出生的週年紀念日。這個邏輯會說我的生日已經過去了 - 但在9月份我很確定我的妻子會烘烤我的生日蛋糕:) –
@JeffreyKemp Zoink!你是對的。我花了一些時間在面對現實之前。我用另一種解決方案更新了答案。感謝您的解釋。 – Wolf