簡體   English   中英

如何在 Oracle 中獲取一周的第一天和最后一天?

[英]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()))函數調用更好的估計。

你可以試試這個方法:

  1. 獲取當前日期。

  2. 添加等於當前日期年份與指定年份之間的差的年數。

  3. 減去最后獲得日期的星期數的天數(它會給我們某個星期的最后一天)。

  4. 添加上次獲取日期的周數與指定周數之間的差的周數,這將產生所需周的最后一天。

  5. 減去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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM