2013-04-29 6 views
6

Last_value функция окна doesn't исправно работает.Функция окна Last_value не работает должным образом

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?

+0

Это относится к ** Microsoft SQL Server ** а – Jaider

ответ

5

first_value и last_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 и читать особенно раздел кадрирования. Не то, чтобы предложение по умолчанию для функций, принимающих предложение windowing, равно RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW, что объясняет, почему один заказ работает, а другой нет!

9

В аналитических функциях вам необходимо указать диапазон окон. По умолчанию это between unbounded preceding and current row, который, как я полагаю, не требует пояснений.

В принципе, это то, что происходит, когда вы задаете partition by customer_id order by valid_from asc:

  1. Oracle принимает все строки, соответствующие текущей строки customer id
  2. Он заказывает их в порядке возрастания valid_from
  3. Он образует окно, начиная с минимум valid_from и заканчивается текущей строкой valid_from.
  4. Он оценивает last_value, который возвращает текущую строку valid_from.

Что вам нужно сделать, это указать непрерывный диапазон:

16:53:00 [email protected]> 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 [email protected]>/

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 
Смежные вопросы