oracle周数计算

来源:百度文库 编辑:神马文学网 时间:2024/05/01 21:31:33
===========================================================
作者: keyneslin(http://keyneslin.itpub.net)
发表于: 2005.04.29 14:58
分类: ORACLE
出处: http://keyneslin.itpub.net/post/5557/28126
---------------------------------------------------------------
================================================
--日期计算,算第n周的第一天及最后一天是几号。  by keynes 2005.04.29
================================================
-- ww的算法为每年1月1日为第一周开始,date+6为每一周结尾
-- 例如20050101为第一周的第一天,而第一周的最后一天为20050101+6=20050107
-- 公式 每周第一天  :date + 周 * 7 - 7
--      每周最后一天:date + 周 * 7 - 1
不管怎么编排格式都会跑掉,真气人 ~><~
=========================================================================
--日期计算,算第n周的第一天及最后一天是几号。  by keynes 2005.04.29
=========================================================================
-- ww的算法为每年1月1日为第一周开始,date+6为每一周结尾
-- 例如20050101为第一周的第一天,而第一周的最后一天为20050101+6=20050107
-- 公式 每周第一天  :date + 周 * 7 - 7
--      每周最后一天:date + 周 * 7 - 1
-- 如果以ww格式为主,第1、17周的起迄如下
127.0.0.1:asdb:WF>select to_date(‘20050101‘,‘yyyymmdd‘) + 1*7-7,to_date(‘20050101‘,‘yyyymmdd‘) + 1*7-1 from dual;
TO_DATE(‘ TO_DATE(‘
--------- ---------
01-JAN-05 07-JAN-05
127.0.0.1:asdb:WF>select to_date(‘20050101‘,‘yyyymmdd‘) + 17*7-7,to_date(‘20050101‘,‘yyyymmdd‘) + 17*7-1 from dual;
TO_DATE(‘ TO_DATE(‘
--------- ---------
23-APR-05 29-APR-05
Elapsed: 00:00:00.00
-- 验证如下
127.0.0.1:asdb:WF>select to_char(to_date(‘20050422‘,‘yyyymmdd‘),‘ww‘) as weekn,to_char(to_date(‘20050423‘,‘yyyymmdd‘),‘ww‘) as week1,to_char(to_date(‘20050429‘,‘yyyymmdd‘),‘ww‘) as week2,to_char(to_date(‘20050430‘,‘yyyymmdd‘),‘ww‘) as weekn2 from dual;
WEEK WEEK WEEK WEEK
---- ---- ---- ----
16   17   17   18
Elapsed: 00:00:00.00
127.0.0.1:asdb:WF>
-- iw的算法为星期一至星期日算一周,且每年的第一个星期一为第一周,
-- 例如20050101为星期六,所以用iw的算法是前年的53周,而20050103之后才是第一周的开始。
-- 公式 每周第一天  :next_day(date) + 周 * 7 - 7
--      每周最后一天:next_day(date) + 周 * 7 - 1
-- 如果以iw格式为主,第1、17周的起迄如下
127.0.0.1:asdb:WF>select next_day(to_date(‘20050101‘,‘yyyymmdd‘),‘MONDAY‘)+ 1 * 7 - 7 as first_day,next_day(to_date(‘20050101‘,‘yyyymmdd‘),‘MONDAY‘)+ 1 * 7 - 1 as last_day from dual;
FIRST_DAY LAST_DAY
--------- ---------
03-JAN-05 09-JAN-05
Elapsed: 00:00:00.00
127.0.0.1:asdb:WF>
127.0.0.1:asdb:WF>select next_day(to_date(‘20050101‘,‘yyyymmdd‘),‘MONDAY‘)+ 17 * 7 - 7 as first_day,next_day(to_date(‘20050101‘,‘yyyymmdd‘),‘MONDAY‘)+ 17 * 7 - 1 as last_day from dual;
FIRST_DAY LAST_DAY
--------- ---------
25-APR-05 01-MAY-05
Elapsed: 00:00:00.00
127.0.0.1:asdb:WF>
-- 验证如下
127.0.0.1:asdb:WF>select to_char(to_date(‘20050424‘,‘yyyymmdd‘),‘iw‘) as weekn,to_char(to_date(‘20050425‘,‘yyyymmdd‘),‘iw‘) as week1,to_char(to_date(‘20050501‘,‘yyyymmdd‘),‘iw‘) as week2,to_char(to_date(‘20050502‘,‘yyyymmdd‘),‘iw‘) as weekn2 from dual;
WEEK WEEK WEEK WEEK
---- ---- ---- ----
16   17   17   18
Elapsed: 00:00:00.00
其它:
--== 查今天是 "本月" 的第几周
SELECT TO_CHAR(SYSDATE,‘WW‘) - TO_CHAR(TRUNC(SYSDATE,‘MM‘),‘WW‘) + 1 AS "weekOfMon" from dual;

SELECT TO_CHAR(SYSDATE,‘W‘) AS "weekOfMon" from dual;
--== 查今天是 "今年" 的第几周
select to_char(sysdate,‘ww‘) from dual;

select to_char(sysdate,‘iw‘) from dual;
附注:
上文所提之iw及ww格式在doc内解释如下
IW = Week of year (1-52 or 1-53) based on the ISO standard
WW = Week of year (1-53) where week 1 starts on the first day of the year and continues to the seventh day of the year.
参考文件:
Format Models:http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96540/sql_elements4a.htm#34512
oracle周数计算(续)
===========================================================
作者: keyneslin(http://keyneslin.itpub.net)
发表于: 2005.05.10 09:31
分类: ORACLE
出处: http://keyneslin.itpub.net/post/5557/29157
---------------------------------------------------------------
本篇是接续前一篇,因有朋友(allenc)要计算oracle的周数日期起迄,
所以测试了一下,
测试结果如下:
-- 特殊周数计算
-- 星期日到星期六为一周(与ww及iw算法不同)
-- 例2005年的第一周起迄是同一天,是20050101
-- 例2004年的第一周起为20040101迄为20040103
-- 计算第一周的天数
create or replace function fdf(p_date in date) return number
is
begin
-- 检查是否传入要计算那一年的一月一日
if to_char(to_char(p_date,‘ddd‘)) <> ‘001‘ then
return null;
end if;
--如果第一周的第一天刚好也是最后一天时,传回1
if to_char(p_date,‘d‘) <> ‘7‘ then
return (next_day(p_date,‘SATURDAY‘) - p_date +1);
else
return 1;
end if;
exception
when others then
dbms_output.put_line(sqlerrm);
end;
计算公式:
起            :decode(周,1,计算当年的一月一日,计算当年的一月一日 + (fdf(计算当年的一月一日) + (周 - 2)*7)) as 起
迄(第一种算法):decode(周,53,to_date(to_char(计算当年的一月一日,‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),计算当年的一月一日 + (fdf(计算当年的一月一日) + (周-1)*7-1)) as 迄
迄(第二种算法):decode(周,53,last_day(trunc(计算当年的一月一日,‘mm‘)+340),计算当年的一月一日 + (fdf(计算当年的一月一日) + (周-1)*7-1)) as 迄
上面的参数部份,"计算当年的一月一日"为date type,"周"为number type
传回值一律是date型态
例如:
--2004年第1周
select decode(1,1,to_date(‘20040101‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (1 - 2)*7)) as s_week,decode(1,53,to_date(to_char(to_date(‘20040101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (1-1)*7-1)) as e_week from dual;
--2004年第3周
select decode(3,1,to_date(‘20040101‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (3 - 2)*7)) as s_week,decode(3,53,to_date(to_char(to_date(‘20040101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (3-1)*7-1)) as e_week from dual;
--2004年第53周
select decode(53,1,to_date(‘20040101‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (53 - 2)*7)) as s_week,decode(53,53,to_date(to_char(to_date(‘20040101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (53-1)*7-1)) as e_week from dual;
--2005年第1周
select decode(1,1,to_date(‘20050101‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (1 - 2)*7)) as s_week,decode(1,53,to_date(to_char(to_date(‘20050101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (1-1)*7-1)) as e_week from dual;
--2005年第3周
select decode(3,1,to_date(‘20050101‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (3 - 2)*7)) as s_week,decode(3,53,to_date(to_char(to_date(‘20050101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (3-1)*7-1)) as e_week from dual;
--2005年第53周
select decode(53,1,to_date(‘20050101‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (53 - 2)*7)) as s_week,decode(53,53,to_date(to_char(to_date(‘20050101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (53-1)*7-1)) as e_week from dual;
--2005年第53周方法2
select decode(53,1,to_date(‘20050101‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (53 - 2)*7)) as s_week,decode(53,53,last_day(trunc(to_date(‘20050101‘,‘yyyymmdd‘),‘mm‘)+340),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (53-1)*7-1)) as e_week from dual;
结果如下:
127.0.0.1:asdb:WF>--2004年第1周
127.0.0.1:asdb:WF>select decode(1,1,to_date(‘20040101‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (1 - 2)*7)) as s_week,decode(1,53,to_date(to_char(to_date(‘20040101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (1-1)*7-1)) as e_week from dual;
S_WEEK    E_WEEK
--------- ---------
01-JAN-04 03-JAN-04
Elapsed: 00:00:00.00
127.0.0.1:asdb:WF>--2004年第3周
127.0.0.1:asdb:WF>select decode(3,1,to_date(‘20040101‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (3 - 2)*7)) as s_week,decode(3,53,to_date(to_char(to_date(‘20040101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (3-1)*7-1)) as e_week from dual;
S_WEEK    E_WEEK
--------- ---------
11-JAN-04 17-JAN-04
Elapsed: 00:00:00.00
127.0.0.1:asdb:WF>--2004年第53周
127.0.0.1:asdb:WF>select decode(53,1,to_date(‘20040101‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (53 - 2)*7)) as s_week,decode(53,53,to_date(to_char(to_date(‘20040101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20040101‘,‘yyyymmdd‘) + (fdf(to_date(‘20040101‘,‘yyyymmdd‘)) + (53-1)*7-1)) as e_week from dual;
S_WEEK    E_WEEK
--------- ---------
26-DEC-04 31-DEC-04
Elapsed: 00:00:00.01
127.0.0.1:asdb:WF>
127.0.0.1:asdb:WF>--2005年第1周
127.0.0.1:asdb:WF>select decode(1,1,to_date(‘20050101‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (1 - 2)*7)) as s_week,decode(1,53,to_date(to_char(to_date(‘20050101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (1-1)*7-1)) as e_week from dual;
S_WEEK    E_WEEK
--------- ---------
01-JAN-05 01-JAN-05
Elapsed: 00:00:00.00
127.0.0.1:asdb:WF>--2005年第3周
127.0.0.1:asdb:WF>select decode(3,1,to_date(‘20050101‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (3 - 2)*7)) as s_week,decode(3,53,to_date(to_char(to_date(‘20050101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (3-1)*7-1)) as e_week from dual;
S_WEEK    E_WEEK
--------- ---------
09-JAN-05 15-JAN-05
Elapsed: 00:00:00.00
127.0.0.1:asdb:WF>--2005年第53周
127.0.0.1:asdb:WF>select decode(53,1,to_date(‘20050101‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (53 - 2)*7)) as s_week,decode(53,53,to_date(to_char(to_date(‘20050101‘,‘yyyymmdd‘),‘yyyy‘)||‘12‘||‘31‘,‘yyyymmdd‘),to_date(‘20050101‘,‘yyyymmdd‘) + (fdf(to_date(‘20050101‘,‘yyyymmdd‘)) + (53-1)*7-1)) as e_week from dual;
S_WEEK    E_WEEK
--------- ---------
25-DEC-05 31-DEC-05
Elapsed: 00:00:00.01
127.0.0.1:asdb:WF>