简体   繁体   English

如何在Oracle中生成一周的第一天、一周的最后一天和两个日期之间的周数

[英]How to generate the first day of the week, the last day of the week and week number between two dates in Oracle

I would like to insert in table:我想在表中插入:

  • the first day of the week starting from Monday.从星期一开始的一周的第一天。
  • the last day of the week as Sunday.一周的最后一天为星期日。
  • the WEEK number => (1-52 or 1-53) based on the ISO standard. WEEK 编号 =>(1-52 或 1-53)基于 ISO 标准。

First i tried to select first day, the last day and week number for specific date and it's works:首先,我尝试 select 第一天,特定日期的最后一天和周数,它的工作原理:

WITH ranges AS
(
SELECT to_date('29-10-2012', 'dd-MM-yyyy') AS DATE_TEST FROM DUAL
)
SELECT DATE_TEST "DATE",
TO_CHAR( NEXT_DAY( TRUNC(DATE_TEST) , 'SUNDAY' )) "WEEK END DATE",
TO_CHAR(TO_DATE(DATE_TEST,'DD-MON-YYYY'),'WW')+1 "WEEK NUMBER"
FROM ranges ;

But now i would like to display this data between two dates, but i get result only for the start_date.但现在我想在两个日期之间显示这些数据,但我只得到 start_date 的结果。 someone can help please.有人可以帮忙。

after, when all good i will insert all in the table.之后,当一切都好时,我会将所有内容都插入表中。

Thanks谢谢

WITH ranges AS(
   select to_date('29-OCT-2012', 'dd-MM-yyyy') START_DATE, 
       to_date('31-DEC-2016', 'dd-MM-yyyy') END_DATE 
from  dual 
)
SELECT START_DATE "DATE",
TO_CHAR( NEXT_DAY( TRUNC(START_DATE) , 'SUNDAY' )) "WEEK END DATE",
TO_CHAR(TO_DATE(START_DATE,'DD-MON-YYYY'),'WW')+1 "WEEK NUMBER"
FROM ranges ;

Looks like you're looking for a calendar .看起来您正在寻找日历

Based on your RANGES CTE, there's another - calendar which utilizes hierarchical query to create all dates between start_date and end_date .根据您的RANGES CTE,还有另一个calendar ,它利用分层查询来创建start_dateend_date之间的所有日期。 Once you have all dates, extract values you're interested in.获得所有日期后,提取您感兴趣的值。

SQL> with
  2  ranges as
  3    (select to_date('29-OCT-2012', 'dd-MM-yyyy') start_date,
  4            to_date('31-DEC-2016', 'dd-MM-yyyy') end_date
  5     from dual
  6    ),
  7  calendar as
  8    (select start_date + level - 1 as datum
  9     from ranges
 10     connect by level <= end_date - start_date + 1
 11    )
 12  select
 13    min(datum) start_date,
 14    min(next_day(datum, 'sunday')) week_end_date,
 15    to_char(datum, 'ww') week_number
 16  from calendar
 17  group by to_char(datum, 'yyyy'), to_char(datum, 'ww')
 18  order by 1;

START_DATE WEEK_END_D WE
---------- ---------- --
29-10-2012 04-11-2012 44
04-11-2012 11-11-2012 45
11-11-2012 18-11-2012 46
18-11-2012 25-11-2012 47
25-11-2012 02-12-2012 48
<snip>
09-12-2016 11-12-2016 50
16-12-2016 18-12-2016 51
23-12-2016 25-12-2016 52
30-12-2016 01-01-2017 53

222 rows selected.

SQL>

Format WW returns 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, see Datetime Format Elements格式WW返回一年中的第几周 (1-53),其中第 1 周从一年的第一天开始并持续到一年的第七天,请参阅日期时间格式元素

In order to get the week number according to ISO-8601 standard use format IW .为了根据 ISO-8601 标准使用格式IW获得周数。 I would suggest like this:我会建议这样:

WITH ranges AS(
    SELECT 
        DATE '2012-10-29' START_DATE,
        DATE '2016-12-31' END_DATE 
    FROM dual 
)
SELECT 
    START_DATE, END_DATE,
    TRUNC(START_DATE + 7*(LEVEL-1), 'IW') AS Week_Start_Date,
    TRUNC(START_DATE + 7*(LEVEL-1), 'IW') + 6 AS Week_End_Date,
    TO_CHAR(TRUNC(START_DATE + 7*(LEVEL-1)), 'IYYY-"W"IW') WEEK_NUMBER
FROM ranges
CONNECT BY START_DATE + 7*(LEVEL-1) <= END_DATE;

Here is a way to make the common table expression return a range of dates.这是一种使公用表表达式返回日期范围的方法。

with ranges (dt) as (
   select to_date('29-OCT-2012', 'dd-MM-yyyy') as dt
   from dual
   
   union all
   select ranges.dt+1
   from ranges
   where ranges.dt < to_date('31-DEC-2016', 'dd-MM-yyyy')
)

Then you can use that to calculate the other values.然后你可以用它来计算其他值。

SELECT dt "DATE"
, TO_CHAR(NEXT_DAY(TRUNC(dt), 'SUNDAY')) "WEEK END DATE"
, TO_CHAR(TO_DATE(dt,'DD-MON-YYYY'),'WW') + 1 "WEEK NUMBER"
, cast(TO_CHAR(dt, 'WW') as int) + 
  case when cast(TO_CHAR(dt, 'D') as int) < cast(TO_CHAR(trunc(dt, 'year'), 'D') as int) then 1 else 0 end  WeekNumberInYear

FROM ranges ;

If you want to have all of your date calculations done at once, check out an example here: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=35e407af3b5bf711bb7ae53b8cf0e608如果您想一次完成所有日期计算,请在此处查看示例: https://dbfiddle.uk/?rdbms=oracle_18&fiddle=35e407af3b5bf711bb7ae53b8cf0e608

How are you?你好吗?

to help, I tried to do some research, I found these links.为了提供帮助,我试图做一些研究,我找到了这些链接。

enter link description here 在此处输入链接描述

enter link description here 在此处输入链接描述

I found:我发现:

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

and

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 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 来自双

and

select sysdate AS today, TRUNC(next_day(sysdate,'MONDAY')-8) as DOMINGO, TRUNC(next_day(sysdate,'SATURDAY')) as SABADO from dual select sysdate AS 今天,TRUNC(next_day(sysdate,'MONDAY')-8) 作为 DOMINGO,TRUNC(next_day(sysdate,'SATURDAY')) 作为 SABADO 从 dual

I don't have oracle here so I couldn't test it well but it should solve what you need, anything let me know:)我这里没有 oracle 所以我不能很好地测试它,但它应该可以解决你的需要,任何让我知道:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM