添加 row_number() 时 Oracle 值发生变化

Oracle values change when row_number() added

我有一个 Oracle 查询,它使用 DUAL 在子查询中生成日期列表,以及确定工作日的情况:

    SELECT DATES
        ,case when to_char(DATES, 'd') in (1,7)
         then 0
        else 1 end as business_day
    FROM (
        SELECT to_date('1/1/2020','MM/DD/YYYY') + (LEVEL -1) AS DATES
        FROM DUAL connect by level <=(to_date('1/1/2021','MM/DD/YYYY') - to_date('1/1/2020','MM/DD/YYYY'))
    ) L1

到目前为止一切顺利。现在,当我将其嵌套在子查询中并添加 row_number() 函数时,我所有的 business_day 值都变为 0。如果我删除 row_number() 函数,business_day恢复正常。

SELECT L2.DATES
, L2.business_day
, row_number() OVER (PARTITION BY L2.business_day ORDER BY L2.DATES ASC) as dateindex
FROM (
    SELECT DATES
        ,case when to_char(DATES, 'd') in (1,7)
         then 0
        else 1 end as business_day
    FROM (
        SELECT to_date('1/1/2020','MM/DD/YYYY') + (LEVEL -1) AS DATES
        FROM DUAL connect by level <=(to_date('1/1/2021','MM/DD/YYYY') - to_date('1/1/2020','MM/DD/YYYY'))
    ) L1
) L2

知道添加新列如何导致另一个值发生变化吗?

我怀疑你没有注意实际日期; 运行 你的代码在 this db<>fiddle, 第一个查询 returns:

DATES     | BUSINESS_DAY
:-------- | -----------:
01-JAN-20 |            1
02-JAN-20 |            1
03-JAN-20 |            1
04-JAN-20 |            1
05-JAN-20 |            0
06-JAN-20 |            0
07-JAN-20 |            1
08-JAN-20 |            1
09-JAN-20 |            1
10-JAN-20 |            1
11-JAN-20 |            1
...

而第二个 returns:

DATES     | BUSINESS_DAY | DATEINDEX
:-------- | -----------: | --------:
05-JAN-20 |            0 |         1
06-JAN-20 |            0 |         2
12-JAN-20 |            0 |         3
13-JAN-20 |            0 |         4
19-JAN-20 |            0 |         5
20-JAN-20 |            0 |         6
26-JAN-20 |            0 |         7
27-JAN-20 |            0 |         8
02-FEB-20 |            0 |         9
03-FEB-20 |            0 |        10
...

所有 business_day 值确实为零...或者至少,如果您只查看结果集的开头。如果再往下看:

...
27-DEC-20 |            0 |       103
28-DEC-20 |            0 |       104
01-JAN-20 |            1 |         1
02-JAN-20 |            1 |         2
03-JAN-20 |            1 |         3
04-JAN-20 |            1 |         4
...

您没有 order-by 子句,并且内部分析处理恰好 return 以您不期望的顺序进行。如果你添加一个 order-by 那么它看起来更明智,如 this db<>fiddle:

DATES     | BUSINESS_DAY | DATEINDEX
:-------- | -----------: | --------:
01-JAN-20 |            1 |         1
02-JAN-20 |            1 |         2
03-JAN-20 |            1 |         3
04-JAN-20 |            1 |         4
05-JAN-20 |            0 |         1
06-JAN-20 |            0 |         2
07-JAN-20 |            1 |         5
08-JAN-20 |            1 |         6
09-JAN-20 |            1 |         7
10-JAN-20 |            1 |         8
11-JAN-20 |            1 |         9
12-JAN-20 |            0 |         3
...

顺便说一下,'d' 格式元素是 NLS 敏感的,因此其他人 运行 在具有不同设置的会话中使用此代码可能会看到不同的结果。这样做会更安全:

when to_char(DATES, 'Dy', 'NLS_DATE_LANGUAGE=ENGLISH') in ('Sat', 'Sun')