假设我输入WeekNo:14,查询应返回From Date:2016年4月4日,因为第14周从4月4日开始到4月10日
select to_date('14','iw') FROM dual;
答案 0 :(得分:0)
with dates as (select to_char(
to_date('1.01.'||extract(year from sysdate),'dd.mm.yyyy' ) + level -1
,'IW') we,
to_date('1.01.'||extract(year from sysdate),'dd.mm.yyyy' ) + level -1 da
from dual
connect by level <= 365 + 10 )
select * from (
select case
when -- we = null if number of week in jan > 1,2,3,4....
((to_number(we) > 40 )
and extract(year from sysdate) = extract(year from da)
and extract(month from da) = '01') or
-- we = null when current year < year of da
(extract(year from sysdate) != extract(year from da))
then
null
else we
end we,
da
from dates
)
where we = 14
and rownum = 1
答案 1 :(得分:0)
如果将年份附加到您要查找的那一周不是问题,您也可以使用:
SELECT (TRUNC ( TO_DATE (SUBSTR ('201627', 1, 4) || '0131', 'YYYY'|| 'MMDD'), 'IYYY')
+ ( 7 * ( TO_NUMBER (SUBSTR ('201627', 5)) - 1)) ) AS iw_Monday
FROM dual
在此示例中,201627
是您要查找的YYYYIW
。
它将返回该周的星期一日期。
在Oracle forums找到它,那里还有其他一些解决方案。我发现这个是最优雅的。
优势在于您可以执行SELECT
中的所有操作,并且您不需要函数或PL / SQL或WHERE
子句。
缺点:您必须追加年份并指定搜索周2次,除非您使用变量
答案 2 :(得分:0)
处理ISO-Weeks并非易事,例如2016年1月1日是 2015 的第53周,请参阅
select to_char(date '2016-01-01', 'iyyy-"W"iw') from dual;
因此,仅提供没有(ISO-)年份的周数是不明确的 - 虽然很明显,因为你不在新年之前。
前段时间我写了这个函数来从ISO-Week获取日期。
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;
当然,你可以选择NEXT_DAY(TO_DATE( YEAR || '0104', 'YYYYMMDD' ) - 7, 'MONDAY') + ( week - 1 ) * 7;
,但是如果有人使用了错误的年份,那么这不会是错误安全的。
答案 3 :(得分:0)
这是一个简单而直接的计算,利用各种Oracle日期函数。由于它与Oracle已经算作ISO周等的比较,它不应该受到其他解决方案正确指出的任何困难并使用附加代码解决。
公式中的“幻数”:iw
应该是绑定变量,可能是select trunc(sysdate, 'iw') - 7 * (to_number(to_char(trunc(sysdate), 'iw')) - 14) as dt
from dual;
DT
----------
2016-04-04
1 row selected.
,或者是在查询中输入ISO周数的其他机制。
anchor