3

Shouldn't first_value() ordered descending give the same results as last_value() ordered ascending? I ran the following query and got the results attached below the query.

select random_date, trunc(random_date,'MM') random_month, random_value,
first_value(random_value) over (partition by trunc(random_date,'MM') order by random_date desc) first_,
last_value(random_value) over (partition by trunc(random_date,'MM') order by random_date) last_
from 
(select to_date(round (dbms_random.value (1, 28))
        || '-'
        || round (dbms_random.value (02, 03))
        || '-'
        || round (dbms_random.value (2014, 2014)),
        'DD-MM-YYYY') + level - 1 random_date,
        round(100*(dbms_random.value)) random_value
from dual
connect by level <= 10) order by 2, 1;

enter image description here

MontyPython
  • 2,906
  • 11
  • 37
  • 58
  • Maybe off topic: what is your Oracle version? This area of SQL used to be very buggy in early 11g releases. Analytic functions were evaluated in "wrong" order. – ibre5041 Mar 13 '15 at 08:57

3 Answers3

3

You forgot about a moving window used for analytical functions. See the difference (used rows between unbounded preceding and unbounded following):

SQL> select random_date, trunc(random_date,'MM') random_month, random_value,
  2  first_value(random_value) over (partition by trunc(random_date,'MM') order by random_date desc rows between unbounded preceding and unbounded following) first_,
  3  last_value(random_value) over (partition by trunc(random_date,'MM') order by random_date rows between unbounded preceding and unbounded following) last_
  4  from
  5  (select to_date(round (dbms_random.value (1, 28))
  6          || '-'
  7          || round (dbms_random.value (02, 03))
  8          || '-'
  9          || round (dbms_random.value (2014, 2014)),
 10          'DD-MM-YYYY') + level - 1 random_date,
 11          round(100*(dbms_random.value)) random_value
 12  from dual
 13  connect by level <= 10) order by 2, 1;

RANDOM_DATE RANDOM_MONTH RANDOM_VALUE     FIRST_      LAST_
----------- ------------ ------------ ---------- ----------
02.02.2014  01.02.2014             93         75         75
09.02.2014  01.02.2014             78         75         75
11.02.2014  01.02.2014             69         75         75
12.02.2014  01.02.2014             13         75         75
21.02.2014  01.02.2014             91         75         75
25.02.2014  01.02.2014             75         75         75
01.03.2014  01.03.2014             54         80         80
15.03.2014  01.03.2014             37         80         80
16.03.2014  01.03.2014             92         80         80
17.03.2014  01.03.2014             80         80         80

10 rows selected
Sanders the Softwarer
  • 2,478
  • 1
  • 13
  • 28
0

Try this Analytic Functions. To achieve your goald should use rows between unbounded preceding and unbounded.

first_value(random_value) over (partition by trunc(random_date,'MM') order by random_date desc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) first_,
last_value(random_value) over (partition by trunc(random_date,'MM') order by random_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) last_

Full code:

select random_date, trunc(random_date,'MM') random_month, random_value,
first_value(random_value) over (partition by trunc(random_date,'MM') order by random_date desc ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) first_,
last_value(random_value) over (partition by trunc(random_date,'MM') order by random_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) last_

from 
(select to_date(round (dbms_random.value (1, 28))
        || '-'
        || round (dbms_random.value (02, 03))
        || '-'
        || round (dbms_random.value (2014, 2014)),
        'DD-MM-YYYY') + level - 1 random_date,
        round(100*(dbms_random.value)) random_value
from dual
connect by level <= 10) order by 2, 1;
0

As I see you do first_value this is used only for strings but you need it for a number so change it to min and max In a string 10 will be before 2 but in number 2 is before

Zvi W.
  • 13
  • 1
  • 7
  • I did not want min and max. I actually wanted first_value and last_value. I am treating the numbers at strings. – MontyPython Mar 13 '15 at 12:55