中午收到个邮件,问在Oracle中如何取得两个日期间的工作日天数(照中国标准,去掉双休日)。于是写了个小函数,先记在这里,以后没准自己也能用上:)
CREATE OR REPLACE FUNCTION WORKDAYS_BETWEEN( start_date IN DATE, end_date IN DATE )
RETURN NUMBER
AS
m_days NUMBER(4);
m_weeks NUMBER(4);
m_res NUMBER(1);
m_idx NUMBER(1);
BEGIN
m_days := end_date - start_date + 1;
m_weeks := trunc (m_days / 7, 0);
m_res := mod (m_days, 7);
m_idx := 1 + mod (start_date - to_date ('1900-01-01','YYYY-MM-DD'), 7);
if m_res > 0 then
if m_idx = 7 then
m_res := m_res - 1;
elsif m_idx + m_res >= 7 then
m_res := m_res - least (2, m_idx + m_res - 6);
end if;
end if;
return m_weeks * 5 + m_res;
end WORKDAYS_BETWEEN;
/
假设:
1)start_date <= end_date,且两者都不早于1900-01-01(可以很容易去掉这个限制,但不喜欢)
2)m_days和m_weeks都定义为NUMBER(4),如果不够可以放大(不会有这么BT的工作吧)
另外,发邮件的朋友说他的表可能有超过100000行,在select中用函数影响性能。我个人有点奇怪,我的理解是(经验得来,从没正式学过Oracle),复杂的逻辑强行塞在单句select里,几乎必然要求算法的变形,从而导致效率低下。而且自定义函数在第一次执行后都应该是被Oracle引擎载入高速缓冲的,以后再多次执行应该不会影响到效率,除非你连函数调用的开销都要计算在内,这样的话,在查询中根本就不能使用任何函数,包括Oracle自身的函数。
以上牵涉到对Oracle函数的一些理解,不知道正确否。虽然不弄Oracle有一年多了,还是想能得到明确的答案。
阅读(3339) | 评论(0) | 转发(0) |