oracle sql问题,前面的行之间

时间:2018-11-06 17:56:06

标签: sql oracle window-functions

我需要帮助来了解Oracle SQL查询的以下部分。前七个和前七个之间有什么作用?我了解,如果每个帐户回购超过一次,则车辆可以有多个回购日期。但是,这段代码正在像这样构建回购日期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

1 个答案:

答案 0 :(得分:0)

From the documentation

  

解析函数基于一组行来计算合计值。它们与集合函数的不同之处在于,它们为每个组返回多个行。该行组称为窗口 ...

  

ROWS | RANGE

     

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

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

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

  •   
     

...

     

value_expr PRECEDING value_expr FOLLOWING

     

对于RANGE or ROW`:

     
      
  • 如果 value_expr FOLLOWING是起点,则终点必须是 value_expr FOLLOWING

    < / li>   
  • 如果 value_expr PRECEDING是终点,则起点必须是 value_expr PRECEDING

    < / li>   

您的每个子句的前后都使用相同的 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行以查找要使用的值。如果没有匹配的行返回很远,则结果为null。


还要注意,解析子句按日期值排序,并且这些日期不是连续的-但是返回的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天之前,您也会看到与之匹配的内容。