[英]How to get first and last day of week in Oracle?
我需要从一些格式如下的字符串中获取一周的第一天和最后一天:
'201118'
其中 2011 是年份,18 是星期几。 知道星期几,我如何获得一周的第一天和最后一天?
我该怎么做呢?
星期
select TRUNC(sysdate, 'iw') AS iso_week_start_date,
TRUNC(sysdate, 'iw') + 7 - 1/86400 AS iso_week_end_date
from dual;
月
select
TRUNC (sysdate, 'mm') AS month_start_date,
LAST_DAY (TRUNC (sysdate, 'mm')) + 1 - 1/86400 AS month_end_date
from dual;
如果您使用的是 Oracle,此代码可以帮助您:
select
TRUNC(sysdate, 'YEAR') Start_of_the_year,
TRUNC(sysdate, 'MONTH') Start_of_the_month,
TRUNC(sysdate, 'DAY') start_of_the_week,
TRUNC(sysdate+365, 'YEAR')-1 End_of_the_year,
TRUNC(sysdate+30, 'MONTH')-1 End_of_the_month,
TRUNC(sysdate+6, 'DAY')-1 end_of_the_week
from dual;
select
TRUNC(sysdate, 'YEAR') Start_of_the_year,
TRUNC(sysdate+365, 'YEAR')-1 End_of_the_year,
TRUNC(sysdate, 'MONTH') Start_of_the_month,
TRUNC(sysdate+30, 'MONTH')-1 End_of_the_month,
TRUNC(sysdate, 'DAY')+1 start_of_the_week, -- starting Monday
TRUNC(sysdate+6, 'DAY') end_of_the_week -- finish Sunday
from dual;
SELECT NEXT_DAY (TO_DATE ('01/01/'||SUBSTR('201118',1,4),'MM/DD/YYYY')+(TO_NUMBER(SUBSTR('201118',5,2))*7)-3,'SUNDAY')-7 first_day_wk,
NEXT_DAY (TO_DATE ('01/01/'||SUBSTR('201118',1,4),'MM/DD/YYYY')+(TO_NUMBER(SUBSTR('201118',5,2))*7)-3,'SATURDAY') last_day_wk FROM dual
SQL> var P_YEARWEEK varchar2(6)
SQL> exec :P_YEARWEEK := '201118'
PL/SQL procedure successfully completed.
SQL> with t as
2 ( select substr(:P_YEARWEEK,1,4) year
3 , substr(:P_YEARWEEK,5,2) week
4 from dual
5 )
6 select year
7 , week
8 , trunc(to_date(year,'yyyy'),'yyyy') january_1
9 , trunc(trunc(to_date(year,'yyyy'),'yyyy'),'iw') monday_week_1
10 , trunc(trunc(to_date(year,'yyyy'),'yyyy'),'iw') + (week - 1) * 7 start_of_the_week
11 , trunc(trunc(to_date(year,'yyyy'),'yyyy'),'iw') + week * 7 - 1 end_of_the_week
12 from t
13 /
YEAR WE JANUARY_1 MONDAY_WEEK_1 START_OF_THE_WEEK END_OF_THE_WEEK
---- -- ------------------- ------------------- ------------------- -------------------
2011 18 01-01-2011 00:00:00 27-12-2010 00:00:00 25-04-2011 00:00:00 01-05-2011 00:00:00
1 row selected.
问候,
抢。
假设您的意思是相对于一年中的第一天的几周......
SELECT first_day_of_week, first_day_of_week+6 last_day_of_week
FROM (
SELECT TO_DATE(YEAR||'0101','YYYYMMDD') + 7 * (week-1) first_day_of_week
FROM (
SELECT substr(yearweek,1,4) YEAR, to_number(substr(yearweek,5)) week
FROM (
SELECT '201118' yearweek FROM dual
)
)
)
;
另一个解决方案(星期一是第一天):
select
to_char(sysdate - to_char(sysdate, 'd') + 2, 'yyyymmdd') first_day_of_week
, to_char(sysdate - to_char(sysdate, 'd') + 8, 'yyyymmdd') last_day_of_week
from
dual
另一个解决方案是
SELECT
ROUND((TRUNC(SYSDATE) - TRUNC(SYSDATE, 'YEAR')) / 7,0) CANTWEEK,
NEXT_DAY(SYSDATE, 'SUNDAY') - 7 FIRSTDAY,
NEXT_DAY(SYSDATE, 'SUNDAY') - 1 LASTDAY
FROM DUAL
您必须将 cantweek 与年份连接起来
除非这是一次性的数据转换,否则您很有可能会从使用日历表中受益。
除了常规的 ISO 周之外,拥有这样的表格可以非常轻松地过滤或汇总非标准时期的数据。 周通常在公司及其内部部门之间的表现略有不同。 一旦你离开“ISO-land”,内置的日期功能就帮不上忙了。
create table calender(
day date not null -- Truncated date
,iso_year_week number(6) not null -- ISO Year week (IYYYIW)
,retail_week number(6) not null -- Monday to Sunday (YYYYWW)
,purchase_week number(6) not null -- Sunday to Saturday (YYYYWW)
,primary key(day)
);
您可以为“purchase_weeks”或“retail_weeks”创建额外的表,或者简单地动态聚合:
select a.colA
,a.colB
,b.first_day
,b.last_day
from your_table_with_weeks a
join (select iso_year_week
,min(day) as first_day
,max(day) as last_day
from calendar
group
by iso_year_week
) b on(a.iso_year_week = b.iso_year_week)
如果您处理大量记录,动态聚合不会产生显着差异,但如果您执行单行,您也将从创建数周的表中受益。
使用日历表提供了微妙的性能优势,因为优化器可以对静态列提供比嵌套add_months(to_date(to_char()))
函数调用更好的估计。
你可以试试这个方法:
获取当前日期。
添加等于当前日期年份与指定年份之间的差的年数。
减去最后获得日期的星期数的天数(它会给我们某个星期的最后一天)。
添加上次获取日期的周数与指定周数之间的差的周数,这将产生所需周的最后一天。
减去6天得到第一天。
实际上,我做了这样的事情:
select case myconfigtable.valpar
when 'WEEK' then to_char(next_day(datetime-7,'Monday'),'DD/MM/YYYY')|| ' - '|| to_char(next_day(datetime,'Sunday'),'DD/MM/YYYY')
when 'MONTH' then to_char(to_date(yearweek,'yyyyMM'),'DD/MM/YYYY') || ' - '|| to_char(last_day(to_date(yearweek,'yyyyMM')),'DD/MM/YYYY')
else 'NA'
end
from
(
select to_date(YEAR||'01','YYYYMM') + 7 * (WEEK - 1) datetime, yearweek
from
(
select substr(yearweek,1,4) YEAR,
to_number(substr(yearweek,5)) WEEK,
yearweek
from (select '201018' yearweek from dual
)
)
), myconfigtable myconfigtable
where myconfigtable.codpar='TYPEOFPERIOD'
@cem 的回答有一个缺陷,如果sysdate
是星期日,它会返回接下来的星期一。 受到他的回答的启发,以下是一项针对几周的测试:
select
(sysdate - to_char(sysdate-1, 'd') + 1) first_day_of_week --A monday here
from dual
SELECT TRUNC(SYSDATE,'D') "1ST_DAY", TRUNC(SYSDATE,'D') + 6 LAST_DAY FROM DUAL
Truc(sysdate, 'DAY')
从星期一开始
Truc(sysdate, 'DAY')+1
从星期二开始
一周的第一天(星期一):
SELECT TO_DATE(to_char(sysdate,'YYYY')||'0101','YYYYMMDD') + 7 * to_number(to_char(sysdate,'WW')-1)-1 first_day_week FROM dual;
一周的最后一天(星期日):
SELECT TO_DATE(to_char(sysdate,'YYYY')||'0101','YYYYMMDD') + 7 * to_number(to_char(sysdate,'WW')-1)+5 last_day_week FROM dual;
在这些公式中替换您的日期或日期字段对您有用!
我认为这只是一个简单的选择语句。 我希望它有效,因为我无法在家测试它,因为我这里没有 Oracle 数据库;-)
select to_date('201118', 'YYYYWW'), to_date('201118', 'YYYYWW')+7 from dual;
你必须小心,因为WW和IW之间存在差异。 这是一篇解释差异的文章: http : //rwijk.blogspot.com/2008/01/date-format-element-ww.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.