如何在Oracle中获得一周的第一天和最后一天?

时间:2011-04-01 15:31:32

标签: sql oracle

我需要从一些具有以下格式的字符串中获取一周的第一天和最后一天:

'201118'

其中2011年是一年,18是本周的数字。知道一周的数量,我如何得到一周的第一天和最后一天?

我该怎么做?

14 个答案:

答案 0 :(得分:22)

<强> WEEK

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;

答案 1 :(得分:9)

如果您使用的是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;

答案 2 :(得分:2)

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.

的问候,
罗布。

答案 3 :(得分:2)

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

答案 4 :(得分:1)

假设你指的是相对于一年中第一天的周数......

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
    )
  )
)
;

答案 5 :(得分:0)

除非这是一次性数据转换,否则您可能会从使用日历表中受益。

使用这样的表格可以非常轻松地将添加中的非标准期间的数据过滤或汇总到常规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 :(得分:0)

您可以尝试这种方法:

  1. 获取当前日期。

  2. 添加年数,该年数等于当前日期与指定年份之间的差额。

  3. 减去上次获得日期的工作日数量的天数(它会给我们一周的最后一天)。

  4. 添加周数,即最后获得的日期周数与指定周数之间的差值,这将产生所需周数的最后一天。

  5. 减去6天才能获得第一天。

答案 7 :(得分:0)

实际上,我做了类似的事情:

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

这 ( 选择to_date(YEAR ||'01','YYYYMM')+ 7 *(WEEK - 1)datetime,yearweek        从        (        选择substr(yearweek,1,4)年,               to_number(substr(yearweek,5))WEEK,               年周        来自(选择'201018'每周两次             )        ) ),myconfigtable myconfigtable  其中myconfigtable.codpar ='TYPEOFPERIOD'

答案 8 :(得分:0)

又一个解决方案(星期一是第一天):

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

答案 9 :(得分:0)

另一种解决方法是

SELECT 
  ROUND((TRUNC(SYSDATE) - TRUNC(SYSDATE, 'YEAR')) / 7,0) CANTWEEK,
  NEXT_DAY(SYSDATE, 'SUNDAY') - 7 FIRSTDAY,
  NEXT_DAY(SYSDATE, 'SUNDAY') - 1 LASTDAY
FROM DUAL

您必须将年份与年份保持一致

答案 10 :(得分:0)

@cem的答案有一个缺陷,如果{{1}}是星期日,它将返回下一个星期一。 受他的回答启发,以下是针对几个星期的测试:

{{1}}

答案 11 :(得分:-1)

我认为这只是一个简单的选择声明。我希望它有效,因为我无法在家测试它,因为我这里没有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

答案 12 :(得分:-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;

在这些公式中替换您的日期或日期字段对您有用!

答案 13 :(得分:-1)

FirebaseAuth.getInstance().getCurrentUser().getUid()