Oracle analytic functions

I got an email from someone a couple of days ago. The email said

############## 

hi,
      i am having a problem here pls help me
 
this is my i/p and o/p pls tell me logic to develop this
 
input table or file
101,abc,5000
101,abc,2000
101,abc,1000
101,abc,1500
102,aaa,2000
102,aaa,1500
102,aaa,500
103,asa,1000
103,asa,300
103,asa,600
 
o/p table or file
0,101,abc,5000
1,101,abc,3000(i.e.,5000-2000)
2,101,abc,2000(i.e.,3000-1000)
3,101,abc,500(i.e.,2000-1500)
0,102,aaa,2000
1,102,aaa,500(i.e.,2000-1500)
2,102,aaa,0(i.e.,500-500)
0,103,asa,1000
1,103,asa,700(i.e.,1000-300)
2,103,asa,100(i.e.,700-600)
 
thanks and regards
******

##################

Oracle analytic functions were on my mind just like Ray charles (he had Georgia). Even though I knew how to use analytic functions I had to do some research. But I finally got the answer.

First of all the input data didn’t make sense because there was no spelled out requirements provided. After my research, I took a close look at it and found that by adding a sequence number to the table this can be easily done. So I created a test case and assigned a sequence number to the table along with other columns.

This is what I could come up with.

SQL> select banner from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE    10.2.0.1.0      Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production

SQL> Create table t1 ( col1 number, txt varchar2(5), col2 number, seq  number);

Table created.

SQL> desc t1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 COL1                                               NUMBER
 TXT                                                VARCHAR2(5)
 COL2                                               NUMBER
 SEQ                                                NUMBER

SQL> insert into t1 values (101,'abc',5000,1);

1 row created.

SQL> insert into t1 values (101,'abc',2000,2);

1 row created.

SQL> insert into t1 values (101,'abc',1000,3);

1 row created.

SQL> insert into t1 values (101,'abc',1500,4);

1 row created.

SQL> insert into t1 values (102,'aaa',2000,1);

1 row created.

SQL> insert into t1 values (102,'aaa',1500,2);

1 row created.

SQL> insert into t1 values (102,'aaa', 500,3);

1 row created.

SQL> insert into t1 values (103,'asa',1000,1);

1 row created.

SQL> insert into t1 values (103,'asa', 300,2);

1 row created.

SQL> insert into t1 values (103,'asa', 600,3);

1 row created.

SQL> commit;

Commit complete.

SQL> select * from t1 order by COL1, SEQ;

      COL1 TXT         COL2        SEQ
---------- ----- ---------- ----------
       101 abc         5000          1
       101 abc         2000          2
       101 abc         1000          3
       101 abc         1500          4
       102 aaa         2000          1
       102 aaa         1500          2
       102 aaa          500          3
       103 asa         1000          1
       103 asa          300          2
       103 asa          600          3

10 rows selected.

*****You are about to witness the power of analytics in ORACLE.*****

SQL> select  col1,txt,seq
  2   ,first_value(col2) over (partition by col1 order by seq)
  3   - sum(case when seq=1 then 0 else col2 end)
  4   over (partition by col1 order by seq) "HaveFun"
  5   from  t1
  6   order by col1,seq;

      COL1 TXT          SEQ    HaveFun
---------- ----- ---------- ----------
       101 abc            1       5000
       101 abc            2       3000
       101 abc            3       2000
       101 abc            4        500
       102 aaa            1       2000
       102 aaa            2        500
       102 aaa            3          0
       103 asa            1       1000
       103 asa            2        700
       103 asa            3        100

10 rows selected.
Don’t write code for something that can be done so easily if you have the right tools.
hope this helps

cheers
Kirtan

Leave a Comment