添加 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')
我有一个 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')