[英]Oracle SQL - Fiscal Week of Year
I want to calculate the Fiscal Week of the Year with the following rules:我想用以下规则计算一年中的财政周:
A few samples of correct values are provided with the screenshot attached随附的屏幕截图提供了一些正确值的示例
I tried to do something like TO_NUMBER(TO_CHAR(TO_DATE(DATE_ID + 1,'DD-Mon-YY'),'IW')) -21 but towards the end of the Calendar year I start to get negatives我尝试做一些类似 TO_NUMBER(TO_CHAR(TO_DATE(DATE_ID + 1,'DD-Mon-YY'),'IW')) -21 的事情,但在日历年结束时我开始得到否定
SELECT
DATE_ID
, WEEK_OF_YEAR
FROM DATE_DIM
WHERE
DATE_ID IN
(
20190601
, 20190602
, 20190915
, 20191228
, 20191229
, 20200101
, 20200601
, 20200606
, 20200607
)
ORDER BY DATE_ID ASC
;
SELECT TO_CHAR(ADD_MONTHS(SYSDATE,+7),'IW')
FROM dual
Or in your case,或者在你的情况下,
SELECT date_id,TO_CHAR(ADD_MONTHS(TO_DATE(date_id,'YYYYMMDD'),+7),'IW') week_of_year
FROM date_dim
If you don't like the ISO dating where week 1 is the week beginning Sunday during which the 1st of the year falls, you can try offsetting it by moving it back to the previous sunday (TRUNC(..,'D'), then advance a week, then add the 7 months. See if this works for you:如果您不喜欢 ISO 约会,其中第 1 周是从星期日开始的那一周,在此期间是一年中的第一天,您可以尝试通过将其移回前一个星期日来抵消它 (TRUNC(..,'D'),然后提前一周,然后加上 7 个月。看看这是否适合你:
SELECT date_id, TO_CHAR(ADD_MONTHS(TRUNC(date_id,'D') + 7,7),'IW') week_of_year
FROM date_dim
You got confused with your date formats ('yyyymmdd' vs. 'DD-Mon-YY'), so I am using a real date (mydate) in my answer.您对日期格式(“yyyymmdd”与“DD-Mon-YY”)感到困惑,所以我在回答中使用了真实日期 (mydate)。 Convert your string or number to a proper date and you are there:-)将您的字符串或数字转换为正确的日期,您就在那里:-)
The important thing is to check whether your date is >= June 1. Once this is done you can subtract that year's June 1 or the previous year's one.重要的是检查您的日期是否 >= 6 月 1 日。完成此操作后,您可以减去当年的 6 月 1 日或前一年的 6 月 1 日。 Well, more or less:-)嗯,或多或少:-)
select
mydate,
to_char(mydate, 'DY') as tag,
trunc
(
case when to_char(mydate, 'mmdd') >= '0601' then
trunc(mydate + 1, 'iw') + 6 - to_date(to_char(mydate, 'yyyy') || '0601', 'yyyymmdd')
else
trunc(mydate + 1, 'iw') + 6 - to_date(to_char(extract(year from mydate) - 1) || '0601', 'yyyymmdd')
end / 7
) + 1 as fiscal_week
from ...
order by mydate;
Demo: https://dbfiddle.uk/N5pX_5cV演示: https://dbfiddle.uk/N5pX_5cV
UPDATED ANSWER更新的答案
You can try this - provide the date like 31-MAY-19 to start your calendar from 01-JUN-19 and define how many days you want.您可以试试这个 - 提供像 31-MAY-19 这样的日期,让您的日历从 01-JUN-19 开始,并定义您想要的天数。 There is a shift of 5 months as the code was taken from my regular calendar and adjusted the start of week to sunday...Tested OK for periods up to 2 years per run.有 5 个月的转变,因为代码是从我的常规日历中获取的,并将一周的开始调整为星期日……每次运行长达 2 年的时间测试正常。 So if you want 6 years you'll have to run this 3 times...所以如果你想要 6 年,你必须运行 3 次......
WITH
base_calendar AS
(
SELECT CurrDate AS Day_ID,
TO_CHAR(CurrDate,'Day') AS Week_Day_Full,
TO_CHAR(CurrDate,'DY') AS Week_Day_Short,
TO_NUMBER(TRIM(leading '0' FROM TO_CHAR(CurrDate,'D'))) AS Day_Num_of_Week,
--
MAX(CASE WHEN To_Char(CurrDate, 'ddmm') = '2902' THEN EXTRACT(YEAR From CurrDate) END) OVER(Order By CurrDate Rows Between Unbounded Preceding And Current Row) AS last_leap_year,
Count(CASE WHEN ( TO_CHAR(CurrDate,'DY') = 'SUN' And
CurrDate Between To_date('01.06.' || To_Char(EXTRACT(YEAR From CurrDate)), 'dd.mm.yyyy') And To_date('31.05.' || To_Char(EXTRACT(YEAR From CurrDate) + 1), 'dd.mm.yyyy') )
OR
( TO_CHAR(CurrDate,'DY') = 'SUN' And
CurrDate Between To_date('01.06.' || To_Char(EXTRACT(YEAR From CurrDate) - 1), 'dd.mm.yyyy') And To_date('31.05.' || To_Char(EXTRACT(YEAR From CurrDate) ), 'dd.mm.yyyy') )
THEN 1
END) OVER(Order By CurrDate Rows Between Unbounded Preceding And Current Row) AS cnt_sundays
FROM
(
SELECT level n,
-- Calendar starts at the day after this date
TO_DATE('31/05/2019','DD/MM/YYYY') + NUMTODSINTERVAL(level,'DAY') CurrDate
FROM dual
-- Change for the number of days to be added to the table.
CONNECT BY level <= 731
)
)
SELECT DISTINCT
day_id,
CASE WHEN (cnt_sundays + 1 ) - ( (EXTRACT(YEAR From Add_Months(Day_id, - 5)) -EXTRACT(YEAR From MIN(Day_id) OVER()) ) * 53) >= 54 THEN 1
WHEN EXTRACT(YEAR From day_id) <> last_leap_year And day_id > = To_Date('01.06.' || To_Char(EXTRACT(YEAR From day_id)), 'dd.mm.yyyy' )
THEN (cnt_sundays + 1) - ( (EXTRACT(YEAR From Add_Months(Day_id, - 5)) -EXTRACT(YEAR From MIN(Day_id) OVER()) ) * 53) + 1
ELSE (cnt_sundays + 1) - ( (EXTRACT(YEAR From Add_Months(Day_id, - 5)) -EXTRACT(YEAR From MIN(Day_id) OVER()) ) * 53)
END week_of_year,
--
week_day_full,
week_day_short,
CASE week_day_short
WHEN 'SUN' THEN 1
WHEN 'MON' THEN 2
WHEN 'TUE' THEN 3
WHEN 'WED' THEN 4
WHEN 'THU' THEN 5
WHEN 'FRI' THEN 6
WHEN 'SAT' THEN 7
END AS day_num_of_week
FROM base_calendar
ORDER BY day_id
R ESULTS: R 结果:
DAY_ID WEEK_OF_YEAR WEEK_DAY_FULL WEEK_DAY_SHORT DAY_NUM_OF_WEEK
--------- ------------ ------------- -------------- ---------------
01-JUN-19 1 Saturday SAT 7
02-JUN-19 2 Sunday SUN 1
03-JUN-19 2 Monday MON 2
04-JUN-19 2 Tuesday TUE 3
05-JUN-19 2 Wednesday WED 4
... ...
... ...
13-SEP-19 16 Friday FRI 6
14-SEP-19 16 Saturday SAT 7
15-SEP-19 17 Sunday SUN 1
16-SEP-19 17 Monday MON 2
... ...
30-DEC-19 32 Monday MON 2
31-DEC-19 32 Tuesday TUE 3
01-JAN-20 32 Wednesday WED 4
02-JAN-20 32 Thursday THU 5
...
27-FEB-20 40 Thursday THU 5
28-FEB-20 40 Friday FRI 6
29-FEB-20 40 Saturday SAT 7
01-MAR-20 41 Sunday SUN 1
02-MAR-20 41 Monday MON 2
...
29-MAY-20 53 Friday FRI 6
30-MAY-20 53 Saturday SAT 7
31-MAY-20 1 Sunday SUN 1
01-JUN-20 1 Monday MON 2
02-JUN-20 1 Tuesday TUE 3
03-JUN-20 1 Wednesday WED 4
04-JUN-20 1 Thursday THU 5
05-JUN-20 1 Friday FRI 6
06-JUN-20 1 Saturday SAT 7
07-JUN-20 2 Sunday SUN 1
... ...
... ...
22-MAY-21 51 Saturday SAT 7
23-MAY-21 52 Sunday SUN 1
24-MAY-21 52 Monday MON 2
25-MAY-21 52 Tuesday TUE 3
26-MAY-21 52 Wednesday WED 4
27-MAY-21 52 Thursday THU 5
28-MAY-21 52 Friday FRI 6
29-MAY-21 52 Saturday SAT 7
30-MAY-21 53 Sunday SUN 1
31-MAY-21 53 Monday MON 2
731 rows selected
... with year 2025 - part of the result mentioned in comments above... ... 2025 年 - 上面评论中提到的部分结果...
... ...
29-MAY-25 53 Thursday THU 5
30-MAY-25 53 Friday FRI 6
31-MAY-25 53 Saturday SAT 7
01-JUN-25 1 Sunday SUN 1
02-JUN-25 1 Monday MON 2
03-JUN-25 1 Tuesday TUE 3
04-JUN-25 1 Wednesday WED 4
05-JUN-25 1 Thursday THU 5
06-JUN-25 1 Friday FRI 6
07-JUN-25 1 Saturday SAT 7
08-JUN-25 2 Sunday SUN 1
... ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.