簡體   English   中英

如何在Oracle中將周數轉換為星期幾

[英]How do I convert a Week Number to From date of the week in oracle

假設我輸入WeekNo:14,則查詢應返回From Date:2016年4月4日,因為第14周從4月4日到4月10日開始

select to_date('14','iw') FROM dual;

這樣的事情? (適用於當年)那里丟棄了另一年的數據

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

如果將年份附加到要查找的星期不是問題,則也可以使用以下方法:

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論壇上找到了它,那里還有一些其他解決方案。 我發現這是最優雅的。

優點是您可以執行SELECT所有操作,而無需使用函數或PL / SQL或WHERE子句。

缺點:您必須附加年份並指定兩次搜索星期,除非您使用變量

處理ISO周並非易事,例如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; ,但是如果有人使用錯誤的年份,這將不是錯誤的安全措施。

這是利用各種Oracle日期函數的簡單直接的計算。 由於它與Oracle已經算作ISO周之類的東西相比較,因此它不應受到其他解決方案正確指向並使用附加代碼解決的任何困難。

公式中的“幻數” 14應該改為綁定變量,也許是:iw或將ISO周數輸入到查詢中的某種其他機制。

select trunc(sysdate, 'iw') - 7 * (to_number(to_char(trunc(sysdate), 'iw')) - 14) as dt 
from   dual;

DT
----------
2016-04-04

1 row selected.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM