SQL 将日期的IW周数转换为日期范围转换为日期发生的年份
问题描述
计算给定的IW周数的日期范围。在将一些语法合并到我的查询中后,我创建了以下SQL:
SELECT
t.termination_date,
to_char(t.termination_date,'IW') IW_WEEK,
next_day(to_date( to_char(t.termination_date,'IW') *7, 'DDD')-8, 'mon') WEEK_START_DATE,
next_day(to_date( to_char(t.termination_date,'IW') *7, 'DDD'), 'sun') WEEK_END_DATE
FROM
table t
我注意到的是,这些周范围只返回2023年的周范围,即使终止日期是在其他年份。我不确定这是由于next_day()函数的设计还是一种内置行为,将IW周转换为当前年份,但我找不到支持这一点的信息。
我想要做的是根据给定的日期(我的例子中的终止日期)计算日期所在年份的IW周的日期范围。
解决方案
你似乎只想使用TRUNC(date_column, 'IW')
来获取一周的开始日期(周一),然后再加6天获取周日。
如果你想要根据ISO年和ISO周计算一周的起始和结束日期,可以从ISO年的1月4日开始(因为这总是第一个ISO周),然后截断到ISO周的开始并加上7的倍数天数来得到正确的ISO周:
SELECT termination_date,
to_char(termination_date,'IW') AS IW_WEEK,
TRUNC(termination_date,'IW') AS WEEK_START_DATE,
TRUNC(termination_date,'IW') + INTERVAL '6' DAY AS WEEK_END_DATE,
TRUNC(TO_DATE(TO_CHAR(termination_date, 'IYYY') || '-01-04', 'YYYY-MM-DD'), 'IW')
+ INTERVAL '7' DAY * (TO_CHAR(termination_date, 'IW') - 1) AS week_start_date2,
TRUNC(TO_DATE(TO_CHAR(termination_date, 'IYYY') || '-01-04', 'YYYY-MM-DD'), 'IW')
+ INTERVAL '7' DAY * TO_CHAR(termination_date, 'IW') - 1 AS week_end_date2
FROM table_name
就样本数据而言:
CREATE TABLE table_name (termination_date) AS
SELECT DATE '2022-01-06' + LEVEL FROM DUAL CONNECT BY LEVEL <= 15;
输出结果:
TERMINATION_DATE | IW_WEEK | WEEK_START_DATE | WEEK_END_DATE | WEEK_START_DATE2 | WEEK_END_DATE2 |
---|---|---|---|---|---|
2022-01-07 00:00:00 | 01 | 2022-01-03 00:00:00 | 2022-01-09 00:00:00 | 2022-01-03 00:00:00 | 2022-01-09 00:00:00 |
2022-01-08 00:00:00 | 01 | 2022-01-03 00:00:00 | 2022-01-09 00:00:00 | 2022-01-03 00:00:00 | 2022-01-09 00:00:00 |
2022-01-09 00:00:00 | 01 | 2022-01-03 00:00:00 | 2022-01-09 00:00:00 | 2022-01-03 00:00:00 | 2022-01-09 00:00:00 |
2022-01-10 00:00:00 | 02 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 |
2022-01-11 00:00:00 | 02 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 |
2022-01-12 00:00:00 | 02 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 |
2022-01-13 00:00:00 | 02 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 |
2022-01-14 00:00:00 | 02 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 |
2022-01-15 00:00:00 | 02 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 |
2022-01-16 00:00:00 | 02 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 | 2022-01-10 00:00:00 | 2022-01-16 00:00:00 |
2022-01-17 00:00:00 | 03 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 |
2022-01-18 00:00:00 | 03 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 |
2022-01-19 00:00:00 | 03 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 |
2022-01-20 00:00:00 | 03 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 |
2022-01-21 00:00:00 | 03 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 | 2022-01-17 00:00:00 | 2022-01-23 00:00:00 |