Last_value窗口功能无法正常工作

时间:2013-04-29 08:34:57

标签: oracle window-functions

Last_value窗口函数doesn't正常工作。

CREATE TABLE EXAMP2
(
  CUSTOMER_ID  NUMBER(38)                       NOT NULL,
  VALID_FROM   DATE                             NOT NULL
);


Customer_id      Valid_from
-------------------------------------
 9775             06.04.2013 01:34:16
 9775             06.04.2013 20:34:00
 9775             12.04.2013 11:07:01
--------------------------------------

select DISTINCT LAST_VALUE(VALID_FROM) 
  OVER (partition by customer_id ORDER BY VALID_FROM ASC) rn 
from   examp1;

当我使用LAST_VALUE时,我会得到以下行:

06.04.2013 20:34:00
06.04.2013 01:34:16
12.04.2013 11:07:01

当我使用FIRST_VALUE时,我会得到以下行:

select  DISTINCT FIRST_VALUE(VALID_FROM) 
OVER (partition by customer_id ORDER BY VALID_FROM DESC) rn 
from   examp1;

4/12/2013 11:07:01 AM

First_value查询提供正确的输出。我希望从这些查询中获得相同的输出。为什么我有2 different results

2 个答案:

答案 0 :(得分:12)

在分析函数中,您需要指定窗口范围。默认情况下它是between unbounded preceding and current row,我认为这是不言自明的。

基本上,当您指定partition by customer_id order by valid_from asc时会发生这种情况:

  1. Oracle获取与当前行customer id
  2. 匹配的所有行
  3. valid_from
  4. 按升序排序
  5. 它形成一个窗口,从最小valid_from日期开始,以当前行valid_from结束。
  6. 评估last_value,返回当前行的valid_from
  7. 您需要做的是指定一个持续的范围:

    16:53:00 SYSTEM@sandbox> ed
    Wrote file S:\spool\sandbox\BUFFER_SYSTEM_38.sql
    
      1  select last_value(VALID_FROM) OVER (
      2    partition by customer_id
      3    ORDER BY VALID_FROM asc
      4    range between current row and unbounded following
      5  ) rn
      6* from   t
    16:53:21 SYSTEM@sandbox> /
    
    RN
    ---------------------------------------------------------------------------
    04-DEC-13 11.07.01.000000 AM
    04-DEC-13 11.07.01.000000 AM
    04-DEC-13 11.07.01.000000 AM
    
    Elapsed: 00:00:00.01
    

答案 1 :(得分:6)

first_valuelast_value有点特别,因为它们需要一个可以操作的窗口。

您需要添加ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING,如下所示:

select DISTINCT LAST_VALUE(VALID_FROM) OVER (partition by customer_id
  ORDER BY VALID_FROM ASC
  ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) rn
from examp1;

请参阅文档:http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions001.htm#i81407并特别阅读有关窗口的部分。不是接受窗口子句的函数的默认子句是RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW,它解释了为什么一个订单有效而另一个订单无效!