[英]Getting a date for "start of the week", from week and year numbers on Oracle SQL
我一直在处理一个按周对许多记录进行分组的查询。 周数由
to_char(reportdate, 'IW') as "Week",
之后使用GROUP BY
子句。 “周”总是从星期一开始,如果 1 月 1 日不是星期一,则第 1 周将从上一个星期一开始(或者我已经理解了这行代码)。
因此,如果获得如下表(对于三个示例行)
Week Year Sales Visits
32 2017 22 55
33 2017 30 65
01 2019 55 103
我想添加一个带有日期的列,以便它是一周的开始。 我正在考虑使用分组查询作为子查询,然后简单地在后面添加一个列,但我无法完全弄清楚如何将周数和年数映射到这样的日期。
我试过这条线来获取日期
trunc(next_day (trunc(to_date(Yr,'yy'),'yy') -1,'Mon') + (7*(Wk - 1)) -7)
但并不是每一行都成立。
任何为我指明正确方向的想法将不胜感激。
ISO-8601 将一年中的第一周计算为该年大部分天数的第一周。 要在该年中拥有大部分天数,那么它必须包含该年内一周中的至少 4 天,并且必须包含 1 月 4 日。
您可以使用它来计算第一个 iso 周的开始时间:
TO_DATE( year, 'YYYY' )
将给出 1 月 1 日;TRUNC( date_value, 'IW' )
获取一年中第一个等周的星期一测试数据:
CREATE TABLE test_data ( Week, Year, Sales, Visits ) AS
SELECT '32', 2017, 22, 55 FROM DUAL UNION ALL
SELECT '33', 2017, 30, 65 FROM DUAL UNION ALL
SELECT '01', 2019, 55, 103 FROM DUAL;
查询:
SELECT t.*,
TRUNC( TO_DATE( year, 'YYYY' ) + 3, 'IW' ) + 7 * ( week - 1 ) AS week_start
FROM test_data t
输出:
\n周 | 年 | 销售 | 访问 | WEEK_START\n :--- | ---: | ----: | -----: | :---------\n 32 | 2017 | 22 | 55 | 07-AUG-17 \n 33 | 2017 | 30 | 65 | 17 年 8 月 14 日 \n 01 | 2019 | 55 | 103 | 18 年 12 月 31 日 \n
db<> 在这里摆弄
根据 ISO-8601,第一周是 1 月 4 日的那一周。 我使用此函数从 ISO-Week 获取日期:
CREATE OR REPLACE FUNCTION ISOWeekDate(WEEK INTEGER, YEAR INTEGER) RETURN DATE DETERMINISTIC IS
res DATE;
BEGIN
IF WEEK > 53 OR WEEK < 1 THEN
RAISE VALUE_ERROR;
END IF;
res := NEXT_DAY(TO_DATE( YEAR || '0104', 'YYYYMMDD' ) - 7, 'MONDAY') + ( WEEK - 1 ) * 7;
IF TO_CHAR(res, 'fmIYYY') = YEAR THEN
RETURN res;
ELSE
RAISE VALUE_ERROR;
END IF;
END ISOWeekDate;
请注意,没有年份的周数是不够的,因为 ISO-Year 可能与实际年份不同。 请参阅以下示例:
SELECT to_char(DATE '2019-12-31', 'IYYY-"W"IW') from dual;
TO_CHAR(DATE'2019-12-31','IYYY-"W"IW')
--------------------------------------
2020-W01
SELECT ISOWeekDate(1, 2019) from dual;
ISOWEEKDATE(1,2019)
----------------------------
2018-12-31 00:00:00
当然,当您输入的周/年值可靠时,您可以简单地使用SELECT NEXT_DAY(TO_DATE( yr|| '0104', 'YYYYMMDD' ) - 7, 'MONDAY') + ( wk - 1 ) * 7 AS week_start
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.