如何将 DB2 WEEK 函数替换为 Oracle 函数?

How to replace DB2 WEEK function to Oracle function?

我正在尝试用 Oracle DB 替换 DB2。

在 DB2 中,有一个 WEEK 函数,它 returns 一年中的周数。 例如:

SELECT week('2021-01-04') FROM sysibm.sysdummy1

然后我得到 2 的 return(因为 DB2 WEEK 函数将星期日视为一周的第一天。)

但是,在 Oracle 中,如果我进行类似的查询,则会得到不同的值。

SELECT to_char(to_date('2021-01-04', 'YYYY-MM-DD'), 'WW') FROM dual;

我得到值 1(不是 2,因为 Oracle 将 1 月 1 日视为一周的第一天。)

是否有任何其他周转或不同的功能来替代 DB2 WEEK 功能?

Oracle 提供了两个年度周数函数。正如您所发现的,to_char(dt, 'WW') 给出一个数字,其中一周从 1 月 1 日开始,每 7 天递增一次。还有 to_char(dt, 'IW') 给出了 ISO 周数,运行 是周一到周日;在这种情况下,1 月 1 日是第 53 周,2021-01-04 是 2021 年第 1 周的第一天。

Demo on db<>fiddle

Oracle 中没有根据星期几递增周数的函数。您可以编写自己的 PL/SQL 函数来执行此操作。


顺便说一下,Oracle 中一周的第一天是由我们的 NLS 参数决定的。如果我们 运行 使用(比方说)美国设置,星期日是第 1 天;如果我们 运行 使用英国设置,那么星期一是第 1 天。

如果要计算一周的第一天是星期日的周数,则:

SELECT FLOOR(
         (DATE '2021-01-04' - NEXT_DAY( TRUNC( DATE '2021-01-04', 'YY' ) - INTERVAL '7' DAY, 'SUNDAY'))
         / 7
       ) + 1
       AS week
FROM   your_input;

输出 2.

如果你 运行 它有多个输入日期:

WITH your_input ( value ) AS (
  SELECT DATE '2021-01-01' + LEVEL - 1
  FROM   DUAL
  CONNECT BY LEVEL <= 32
)
SELECT value,
       FLOOR(
         (value - NEXT_DAY( TRUNC( value, 'YY' ) - INTERVAL '7' DAY, 'SUNDAY'))
         / 7
       ) + 1
       AS week
FROM   your_input;

然后你得到输出(NLS_DATE_FORMATYYYY-MM-DD (DY)):

VALUE WEEK
2021-01-01 (FRI) 1
2021-01-02 (SAT) 1
2021-01-03 (SUN) 2
2021-01-04 (MON) 2
2021-01-05 (TUE) 2
2021-01-06 (WED) 2
2021-01-07 (THU) 2
2021-01-08 (FRI) 2
2021-01-09 (SAT) 2
2021-01-10 (SUN) 3
2021-01-11 (MON) 3
2021-01-12 (TUE) 3
2021-01-13 (WED) 3
2021-01-14 (THU) 3
2021-01-15 (FRI) 3
2021-01-16 (SAT) 3
2021-01-17 (SUN) 4
2021-01-18 (MON) 4
2021-01-19 (TUE) 4
2021-01-20 (WED) 4
2021-01-21 (THU) 4
2021-01-22 (FRI) 4
2021-01-23 (SAT) 4
2021-01-24 (SUN) 5
2021-01-25 (MON) 5
2021-01-26 (TUE) 5
2021-01-27 (WED) 5
2021-01-28 (THU) 5
2021-01-29 (FRI) 5
2021-01-30 (SAT) 5
2021-01-31 (SUN) 6
2021-02-01 (MON) 6

db<>fiddle here