【问题标题】:Oracle values change when row_number() added添加 row_number() 时 Oracle 值发生变化
【发布时间】:2020-11-14 13:00:37
【问题描述】:

我有一个 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

知道添加新列如何导致其他列的值发生变化吗?

【问题讨论】:

    标签: oracle date sql-order-by window-functions recursive-query


    【解决方案1】:

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

    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
    ...
    

    当第二个返回时:

    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 子句,并且内部的分析处理恰好以您不期望的顺序返回。如果你添加一个 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') 
    

    【讨论】:

    • 我瞎了!我看到了 01-JAN-20,还看到了一些连续的日期,我的大脑认为它仍在按日期排序。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2018-04-07
    • 2023-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多