【问题标题】:oracle sql question, row between precedingoracle sql问题,前面之间的行
【发布时间】:2018-11-06 17:56:06
【问题描述】:

我需要帮助来理解 Oracle SQL 查询的以下部分。 7 PRECEDING 和 7 PRECEDING 之间有什么作用?我了解,如果每个帐户多次回购,则车辆可以有多个回购日期。但是,这段代码正在像这样构建回购日期 1-7,我不确定这到底在做什么。如果有人可以请解释,非常感谢。谢谢

, MIN(D0AL1.CONFIRM_DATE) OVER (PARTITION BY D0AL2.ACCOUNT_NBR
                    ORDER BY D0AL1.ASSIGNMENT_DATE ROWS BETWEEN 7 PRECEDING AND 7 PRECEDING) AS repo_date1
            , MIN(D0AL1.CONFIRM_DATE) OVER (PARTITION BY D0AL2.ACCOUNT_NBR
                    ORDER BY D0AL1.ASSIGNMENT_DATE ROWS BETWEEN 6 PRECEDING AND 6 PRECEDING) AS repo_date2
            , MIN(D0AL1.CONFIRM_DATE) OVER (PARTITION BY D0AL2.ACCOUNT_NBR
                    ORDER BY D0AL1.ASSIGNMENT_DATE ROWS BETWEEN 5 PRECEDING AND 5 PRECEDING) AS repo_date3

【问题讨论】:

标签: sql oracle window-functions


【解决方案1】:

From the documentation:

分析函数根据一组行计算聚合值。它们与聚合函数的不同之处在于它们为每个组返回多行。这组行称为窗口 ...

ROWS | RANGE

这些关键字为每一行定义了一个用于计算函数结果的窗口(一组物理或逻辑行)。然后将该函数应用于窗口中的所有行。窗口从上到下在查询结果集或分区中移动。

  • ROWS 以物理单位(行)指定窗口。

  • RANGE 将窗口指定为逻辑偏移量。

...

value_expr PRECEDINGvalue_expr FOLLOWING

对于RANGE or ROW`:

  • 如果value_exprFOLLOWING是起点,那么终点一定是value_exprFOLLOWING

  • 如果value_exprPRECEDING是终点,那么起点一定是value_exprPRECEDING

您的每个子句都对前后使用相同的 value_expr,因此窗口被限制为正好 1 行;回顾第一行 7 行,第二行回顾 6 行,以此类推。

作为生成内容的演示:

with t (id, dt) as (
  select level, date '2018-01-01' + (level * 3)
  from dual
  connect by level <= 10
)
select id, dt,
  min(id) over (order by dt rows between 7 preceding and 7 preceding) as a,
  min(id) over (order by dt rows between 6 preceding and 6 preceding) as b,
  min(id) over (order by dt rows between 5 preceding and 5 preceding) as c
from t
order by dt;

        ID DT                  A          B          C
---------- ---------- ---------- ---------- ----------
         1 2018-01-04                                 
         2 2018-01-07                                 
         3 2018-01-10                                 
         4 2018-01-13                                 
         5 2018-01-16                                 
         6 2018-01-19                                1
         7 2018-01-22                     1          2
         8 2018-01-25          1          2          3
         9 2018-01-28          2          3          4
        10 2018-01-31          3          4          5

生成的列 a、b 和 c 分别回顾 7、6 和 5 行以找到要使用的值。如果后面没有匹配的行,则结果为空。


还要注意,分析子句是按日期值排序的,这些日期不是连续的 - 但返回的 ID 是连续的。那是因为它按该顺序查看行,而不是它们包含的实际值。如果您改用范围窗口:

select id, dt,
  min(id) over (order by dt range between 7 preceding and 7 preceding) as a,
  min(id) over (order by dt range between 6 preceding and 6 preceding) as b,
  min(id) over (order by dt range between 5 preceding and 5 preceding) as c
from t
order by dt;

        ID DT                  A          B          C
---------- ---------- ---------- ---------- ----------
         1 2018-01-04                                 
         2 2018-01-07                                 
         3 2018-01-10                     1           
         4 2018-01-13                     2           
         5 2018-01-16                     3           
         6 2018-01-19                     4           
         7 2018-01-22                     5           
         8 2018-01-25                     6           
         9 2018-01-28                     7           
        10 2018-01-31                     8           

...结果会非常不同,您只会看到日期 为 5、6 和 7 天前的 ID - 因为我在CTE,结果列b 中只有匹配项。没有任何行在 5 或 7 天前有任何内容,它们只有 6 天前的行(作为 3 的倍数),并且前几行仍然没有匹配那么远。如果您将其延长到 3 天之前,您也会看到这些匹配项。

【讨论】:

    猜你喜欢
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 2020-06-06
    • 2022-11-22
    • 2020-06-06
    • 2022-07-06
    • 1970-01-01
    • 2021-06-17
    相关资源
    最近更新 更多