[英]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.