Вы находитесь на странице: 1из 16

Analytic Functions in Oracle 8i and 9i

Contents
Overview and Introduction
How Analytic Functions Work
The Syntax
Calculate a running Total
Top- !ueries
"xa#ple $
"xa#ple %
Windows
&ange Windows
Co#pute average salary 'or de'ined range
&ow Windows
Accessing &ows Around (our Current &ow
)A*
)"A+
+eter#ine the First ,alue - )ast ,alue o' a *roup
Crossta. or /ivot !ueries
Conclusion
)inks and +ocu#ents
Overview
Analytic Functions0 which have .een availa.le since Oracle 12$230 are designed to
address such pro.le#s as 4Calculate a running total40 4Find percentages within a group40
4Top- 5ueries40 4Co#pute a #oving average4 and #any #ore2 6ost o' these pro.le#s
can .e solved using standard /)-S!)0 however the per'or#ance is o'ten not what it
should .e2 Analytic Functions add extensions to the S!) language that not only #ake
these operations easier to code7 they #ake the# 'aster than could .e achieved with
pure S!) or /)-S!)2 These extensions are currently under review .y the ASI S!)
co##ittee 'or inclusion in the S!) speci'ication2
How Analytic Functions Work ?
Analytic 'unctions co#pute an aggregate value .ased on a group o' rows2 They di''er
'ro# aggregate 'unctions in that they return #ultiple rows 'or each group2 The group o'
rows is called a window and is de'ined .y the analytic clause2 For each row0 a 4sliding4
window o' rows is de'ined2 The window deter#ines the range o' rows used to per'or#
the calculations 'or the 4current row42 Window si8es can .e .ased on either a physical
nu#.er o' rows or a logical interval such as ti#e2
Analytic 'unctions are the last set o' operations per'or#ed in a 5uery except 'or the 'inal
O&+"& 9( clause2 All :oins and all WH"&"0 *&O;/ 9(0 and HA,I* clauses are
co#pleted .e'ore the analytic 'unctions are processed2 There'ore0 analytic 'unctions can
appear only in the select list or O&+"& 9( clause2
The Syntax
The Syntax o' analytic 'unctions is rather straight'orward in appearance
Analytic-Function(<Argument>,<Argument>,...)
OVER (
<Query-Partition-Clause>
<Order-By-Clause>
<Windoing-Clause>
)
o Analytic-Function
Speci'y the na#e o' an analytic 'unction0 Oracle actually provides #any analytic
'unctions such as AVG0 CORR0 COVAR_POP0 COVAR_SAMP0 COUNT0 CUME_DIST0
DENSE_RANK0 FIRST0 FIRST_VALUE0 LAG0 LAST0 LAST_VALUE0 LEAD0 MAX0 MIN0 NTILE0
PERCENT_RANK0 PERCENTILE_CONT0 PERCENTILE_DISC0 RANK0 RATIO_TO_REPORT0
STDDEV0 STDDEV_POP0 STDDEV_SAMP0 SUM0 VAR_POP0 VAR_SAMP0 VARIANCE2
o Aru!ents
Analytic 'unctions take < to = argu#ents2
o "uery-#artition-Clause
The /A&TITIO 9( clause logically .reaks a single result set into groups0 according to
the criteria set .y the partition expressions2 The words 4partition4 and 4group4 are used
synony#ously here2 The analytic 'unctions are applied to each group independently0
they are reset 'or each group2
o Order-$y-Clause
The O&+"& 9( clause speci'ies how the data is sorted within each group >partition?2 This
will de'initely a''ect the outco#e o' any analytic 'unction2
o Windowin-Clause
The windowing clause gives us a way to de'ine a sliding or anchored window o' data0 on
which the analytic 'unction will operate0 within a group2 This clause can .e used to have
the analytic 'unction co#pute its value .ased on any ar.itrary sliding or anchored
window within a group2 6ore in'or#ation on windows can .e 'ound here2
%xa!&le' Calculate a runnin Total
This exa#ple shows the cu#ulative salary within a departe#ent row .y row0 with each
row including a su##ation o' the prior rows salary2
set autotrace traceonly e!"lain
#rea$ on de"tno s$i" %
column ename &ormat A'
column de"tno &ormat (((
column sal &ormat (((((
column se) &ormat (((
SELECT ename "Ename", deptno "Deptno", sal "Sal",
SUM(sal)
OVER (ORDER BY deptno, ename) "Running Total",
SUM(SL)
OVER (!RT"T"O# BY deptno
ORDER BY ename) "Dept Total",
RO$%#UMBER()
OVER (!RT"T"O# BY deptno
ORDER BY E#ME) "Se&"
'ROM emp
ORDER BY deptno, ename
(
*name +e"tno ,al -unning .otal +e"t .otal ,e)
------ ------ ------ ------------- ---------- ----
C/A-0 %1 2341 2341 2341 %
0567 4111 8341 8341 2
95//*- %:11 ;841 ;841 :
A+A9, 21 %%11 (;41 %%11 %
FO-+ :111 %2;41 3%11 2
<O6*, 2(84 %4;24 8184 :
,CO.. :111 %;;24 %1184 3
,95.= ;11 %('24 %1;84 4
A//*6 :1 %'11 2%224 %'11 %
B/A0* 2;41 23184 3341 2
<A9*, (41 24124 4311 :
9A-.56 %241 2'284 ''41 3
.>-6*- %411 28884 ;%41 4
WA-+ %241 2(124 (311 '
*!ecution Plan
---------------------------------------------------
1 ,*/*C. ,.A.*9*6. O"timi?er@C=OO,*
% 1 W56+OW (,O-.)
2 % .AB/* ACC*,, (F>//) OF A*9PA
,tatistics
---------------------------------------------------
1 recursiBe calls
1 d# #loc$ gets
: consistent gets
1 "Cysical reads
1 redo si?e
%'4; #ytes sent Bia ,Q/D6et to client
41: #ytes receiBed Bia ,Q/D6et &rom client
2 ,Q/D6et roundtri"s toE&rom client
% sorts (memory)
1 sorts (dis$)
%3 ros "rocessed
The exa#ple shows how to calculate a 4&unning Total4 (or the entire )uery2 This is
done using the entire ordered result set0 via SUM(sal) OVER (ORDER BY dep!"#
e!a$e)%
Further0 we were a.le to co#pute a running total within each de&art!ent* a total
that would .e reset at the .eginning o' the next depart#ent2 The PARTITION BY dep!"
in that SUM(sal) caused this to happen0 a partitioning clause was speci'ied in the 5uery
in order to .reak the data up into groups2
The RO&_NUMBER() 'unction is used to se)uentially nu!+er the rows returned in
each group0 according to our ordering criteria >a 4Se54 colu#n was added to in order to
display this position?2
The execution plan shows0 that the whole 5uery is very well per'or#ed with only =
consistent gets0 this can never .e acco#plished with standard S!) or even /)-S!)2
To&-, "ueries
How can we get the Top- records .y so#e set o' 'ields @
/rior to having access to these analytic 'unctions0 5uestions o' this nature were
extre#ely di''icult to answer2
There are so#e pro.le#s with Top- 5ueries however7 #ostly in the way people phrase
the#2 It is so#ething to .e care'ul a.out when designing reports2 Consider this
see#ingly sensi.le re5uestA
I '"(ld l)*e +e "p +,ee pa)d sales ,eps -. depa,$e!
The pro.le# with this 5uestion is that it is a#.iguous2 It is a#.iguous .ecause o'
repeated values0 there #ight .e 'our people who all #ake the sa#e salary0 what should
we do then @
)etBs look at three exa#ples0 all use the well known ta.le "6/2
%xa!&le -
Sort the sales people .y salary 'ro# greatest to least2 *ive the 'irst three rows2 I' there
are less then three people in a depart#ent0 this will return less than three records2
set autotrace on e!"lain
#rea$ on de"tno s$i" %
SELECT ) 'ROM (
SELECT deptno, ename, sal, RO$%#UMBER()
OVER (
!RT"T"O# BY deptno ORDER BY sal DESC
) Top* 'ROM emp
)
$+ERE Top* ,- *
E
+*P.6O *6A9* ,A/ .OP:
---------- ---------- ---------- ----------
%1 0567 4111 %
C/A-0 2341 2
95//*- %:11 :
21 ,CO.. :111 %
FO-+ :111 2
<O6*, 2(84 :
:1 B/A0* 2;41 %
A//*6 %'11 2
.>-6*- %411 :
( ros selected.
*!ecution Plan
--------------------------------------------
1 ,*/*C. ,.A.*9*6. O"timi?er@C=OO,*
% 1 F5*W
2 % W56+OW (,O-.)
: 2 .AB/* ACC*,, (F>//) OF A*9PA
This 5uery works .y sorting each partition >or group0 which is the deptno?0 in a
descending order0 .ased on the salary colu#n and then assigning a se5uential row
nu#.er to each row in the group as it is processed2 The use o' a WH"&" clause a'ter
doing this to get :ust the 'irst three rows in each partition2
%xa!&le .
*ive #e the set o' sales people who #ake the top = salaries - that is0 'ind the set o'
distinct salary a#ounts0 sort the#0 take the largest three0 and give #e everyone who
#akes one o' those values2
SELECT ) 'ROM (
SELECT deptno, ename, sal,
DE#SE%R#.()
OVER (
!RT"T"O# BY deptno ORDER BY sal des/
) Top# 'ROM emp
)
$+ERE Top# ,- *
ORDER BY deptno, sal DESC
(
+*P.6O *6A9* ,A/ .OP6
---------- ---------- ---------- ----------
%1 0567 4111 %
C/A-0 2341 2
95//*- %:11 :
01 SCOTT *111 2 ,333 4
'ORD *111 2 ,333 4
<O6*, 2(84 2
A+A9, %%11 :
:1 B/A0* 2;41 %
A//*6 %'11 2
:1 .>-6*- %411 :
%1 ros selected.
*!ecution Plan
--------------------------------------------
1 ,*/*C. ,.A.*9*6. O"timi?er@C=OO,*
% 1 F5*W
2 % W56+OW (,O-. P>,=*+ -A60)
: 2 .AB/* ACC*,, (F>//) OF A*9PA
Here the /%,S%01A,2 'unction was used to get the top three salaries2 We assigned
the dense rank to the salary colu#n and sorted it in a descending order2
The +"S"C&AD 'unction co#putes the rank o' a row in an ordered group o' rows2 The
ranks are consecutive integers .eginning with $2 The largest rank value is the nu#.er o'
uni5ue values returned .y the 5uery2 &ank values are not skipped in the event o' ties2
&ows with e5ual values 'or the ranking criteria receive the sa#e rank2
The +"S"C&AD 'unction does not skip nu#.ers and will assign the sa#e nu#.er to
those rows with the sa#e value2 Hence0 a'ter the result set is .uilt in the inline view0 we
can si#ply select all o' the rows with a dense rank o' three or less0 this gives us
everyone who #akes the top three salaries .y depart#ent nu#.er2
Windows
The windowing clause gives us a way to de'ine a sliding or anchored window o' data0 on
which the analytic 'unction will operate0 within a group2 The de(ault window is an
anchored window that si#ply starts at the 'irst row o' a group an continues to the
current row2
We can set up windows .ased on two criteriaA 1A,3%S o( data values or 1OWS
o((set (ro! the current row2 It can .e said0 that the existance o' an O&+"& 9( in an
analytic 'unction will add a de'ault window clause o' &A*" ;9O;+"+ /&"C"+I*2
That says to get all rows in our partition that ca#e .e'ore us as speci'ied .y the O&+"&
9( clause2
)etBs look at an exa#ple with a sliding window within a group and co#pute the su# o'
the current rowBs SA) colu#n plus the previous % rows in that group2 I' we need a report
that shows the su# o' the current e#ployeeBs salary with the preceding two salaries
within a departe#ent0 it would look like this2
#rea$ on de"tno s$i" %
column ename &ormat A'
column de"tno &ormat (((
column sal &ormat (((((
,*/*C. de"tno G+e"tnoG, ename G*nameG, sal G,alG,
,>9(,A/)
OF*- (PA-.5.5O6 BH de"tno
O-+*- BH ename
RO$S 0 !RECED"#5) G,liding .otalG
F-O9 em"
O-+*- BH de"tno, ename
E
+e"tno *name ,al ,liding .otal
------ ------ ------ -------------
%1 C/A-0 2341 2341
0567 4111 8341
95//*- %:11 ;841
21 A+A9, %%11 %%11
FO-+ :111 3%11
6O#ES 0789 8189 :
SCOTT *111 ;789 <
SM"T+ ;11 =889 >33 Sliding $indo?
:1 A//*6 %'11 %'11
B/A0* 2;41 3341
<A9*, (41 4311
9A-.56 %241 4141
.>-6*- %411 :811
WA-+ %241 3111
The partition clause #akes the S;6 >sal? .e co#puted within each depart#ent0
independent o' the other groups2 Tthe S;6 >sal? is B reset B as the depart#ent changes2
The O&+"& 9( "A6" clause sorts the data within each depart#ent .y "A6"7 this
allows the window clause' 1OWS . #1%C%/4,3* to access the . rows &rior to
the current row in a rou& in order to su# the salaries2
For exa#ple0 i' you note the S)I+I* TOTA) value 'or S54TH is 3 E E F0 which is the
su# o' 1<<0 =<<<0 and %GEF2 That was si#ply S6ITHBs row plus the salary 'ro# the
preceding two rows in the window2
1ane Windows
&ange windows collect rows together .ased on a WH"&" clause2 I' I say B range F
preceding B 'or exa#ple0 this will generate a sliding window that has the set o' all
preceding rows in the group such that they are within F units o' the current row2 These
units #ay either .e nu#eric co#parisons or date co#parisons and it is not valid to use
&A*" with datatypes other than nu#.ers and dates2
%xa!&le
Count the e#ployees which where hired within the last $<< days preceding the own
hiredate2 The range window goes .ack $<< days 'ro# the current rowBs hiredate and
then counts the rows within this range2 The solution ist to use the 'ollowing window
speci'icationA
COU#T()) OVER (ORDER BY @iAedate SC R#5E 211 !RECED"#5)
column ename Ceading G6ameG &ormat a;
column Ciredate Ceading G=iredG &ormat a%1
column CiredateI"re Ceading G=ired-%11G &ormat a%1
column cnt Ceading GCntG &ormat ((
,*/*C. ename, Ciredate, Ciredate-%11 CiredateI"re,
COU#T())
OVER (
ORDER BY @iAedate SC
R#5E 211 !RECED"#5
) cnt
F-O9 em"
O-+*- BH Ciredate A,C
E
6ame =ired =ired-%11 Cnt
-------- ---------- ---------- ---
,95.= %8-+*C-;1 1;-,*P-;1 %
A//*6 21-F*B-;% %2-6OF-;1 2
WA-+ 22-F*B-;% %3-6OF-;1 :
6O#ES 103!R3;2 2:-+*C-;1 :
BL.E 123MY3;2 2%-<A6-;% 3
CLR. 1736U#3;2 123MR3;2 *
.>-6*- 1;-,*P-;% :%-9AH-;% 2
9A-.56 2;-,*P-;% 21-<>6-;% 2
0567 %8-6OF-;% 1(-A>7-;% :
<A9*, 1:-+*C-;% 24-A>7-;% 4
FO-+ 1:-+*C-;% 24-A>7-;% 4
95//*- 2:-<A6-;2 %4-OC.-;% 3
,CO.. 1(-+*C-;2 :%-A>7-;2 %
A+A9, %2-<A6-;: 13-OC.-;2 2
We ordered the single partition .y hiredate ASC2 I' we look 'or exa#ple at the row 'or
C)A&D we can see that his hiredate was <G-H;-1$0 and $<< days prior to that is the
date <$-6A&-1$2 I' we look who was hired .etween <$-6A&-1$ and <G-H;-1$0 we 'ind
HO"S >hiredA <%-A/&-1$? and 9)AD" >hiredA <$-6A(-1$?2 This are = rows including the
current row0 this is what we see in the colu#n 4Cnt4 o' C)A&DBs row2
Co!&ute averae salary (or de(ined rane
As an exa#ple0 co#pute the average salary o' people hired within $<< days .e'ore 'or
each e#ployee2 The 5uery looks like thisA
column ename Ceading G6ameG &ormat a;
column Ciredate Ceading G=iredG &ormat a%1
column CiredateI"re Ceading G=ired-%11G &ormat a%1
column aBgIsal Ceading GABg-%11G &ormat ((((((
,*/*C. ename, Ciredate, sal,
V5(sal)
OVER (
ORDER BY @iAedate SC
R#5E 211 !RECED"#5
) aBg%sal
F-O9 em"
O-+*- BH Ciredate A,C
E
6ame =ired ,A/ ABg-%11
-------- ---------- ---------- -------
,95.= %8-+*C-;1 ;11 ;11
A//*6 21-F*B-;% %'11 %211
WA-+ 22-F*B-;% %241 %2%8
6O#ES 103!R3;2 0789 27C0
BL.E 123MY3;2 0;91 02=7
CLR. 1736U#3;2 0C91 089;
.>-6*- 1;-,*P-;% %411 %(84
9A-.56 2;-,*P-;% %241 %:84
0567 %8-6OF-;% 4111 24;:
<A9*, 1:-+*C-;% (41 2:31
FO-+ 1:-+*C-;% :111 2:31
95//*- 2:-<A6-;2 %:11 24':
,CO.. 1(-+*C-;2 :111 :111
A+A9, %2-<A6-;: %%11 2141
)ook at C)A&D again0 since we understand his range window within the group2 We can
see that the average salary o' %EF1 is e5ual to >%GEFI%1F<I%JF<?-=2 This is the
average o' the salaries 'or C)A&D and the rows preceding C)A&D0 those o' HO"S and
9)AD"2 The data #ust .e sorted in ascending order2
1ow Windows
&ow Windows are physical units7 physical nu#.er o' rows0 to include in the window2 For
exa#ple you can calculate the average salary o' a given record with the >up to F?
e#ployees hired .e'ore the# or a'ter the# as 'ollowsA
set num&ormat ((((
,*/*C. ename, Ciredate, sal,
AF7(sal)
OF*- (O-+*- BH Ciredate SC RO$S 9 !RECED"#5) ABgAsc,
CO>6.(D)
OF*- (O-+*- BH Ciredate SC RO$S 9 !RECED"#5) CntAsc,
AF7(sal)
OF*- (O-+*- BH Ciredate DESC RO$S 9 !RECED"#5) ABg+es,
CO>6.(D)
OF*- (O-+*- BH Ciredate DESC RO$S 9 !RECED"#5) Cnt+es
F-O9 em"
O-+*- BH Ciredate
E
*6A9* =5-*+A.* ,A/ AF7A,C C6.A,C AF7+*, C6.+*,
---------- --------- ----- ------ ------ ------ ------
SM"T+ 283DEC3;1 ;11 ;11 2 %(;; '
LLE# 013'EB3;2 2=11 2011 0 2%13 '
$RD 003'EB3;2 2091 2028 * 213' '
6O#ES 103!R3;2 0789 2=9= C 2'8% '
BL.E 123MY3;2 0;91 2;79 9 2'84 '
CLR. 1736U#3;2 0C91 27;; = 2:4; '
.>-6*- 1;-,*P-;% %411 2%13 ' 2%'8 '
9A-.56 2;-,*P-;% %241 213' ' 23%8 '
0567 %8-6OF-;% 4111 2'8% ' 2:(2 '
<A9*, 1:-+*C-;% (41 2::: ' %4;; 3
FO-+ 1:-+*C-;% :111 2:4; ' %;81 4
95//*- 2:-<A6-;2 %:11 2%'8 ' %;11 :
,CO.. 1(-+*C-;2 :111 23%8 ' 2141 2
A+A9, %2-<A6-;: %%11 2:(2 ' %%11 %
The window consist o' up to 3 rows0 the current row and 'ive rows 4 in 'ront o' 4 this
row0 where 4 in 'ront o' 4 is de'ined .y the O&+"& 9( clause2 With &OW partitions0 we
do not have the li#itation o' &A*" partition - the data #ay .e o' any type and the
order .y #ay include #any colu#ns2 otice0 that we selected out a CO;T>K? as well2
This is use'ul :ust to de#onstrate how #any rows went into #aking up a given average2
We can see clearly that 'or A))"Bs record0 the average salary co#putation 'or people
hired .e'ore hi# used only % records whereas the co#putation 'or salaries o' people
hired a'ter hi# used 32
Accessin 1ows Around 6our Current 1ow
Fre5uently you want to access data not only 'ro# the current row .ut the current row 4
in 'ront o' 4 or 4 .ehind 4 the#2 For exa#ple0 letBs say you need a report that shows0 .y
depart#ent all o' the e#ployees7 their hire date7 how #any days .e'ore was the last
hire7 how #any days a'ter was the next hire2
;sing straight S!) this 5uery would .e di''icult to write2 ot only that .ut its
per'or#ance would once again de'initely .e 5uestiona.le2 The approach I typically took
in the past was either to 4 select a select 4 or write a /)-S!) 'unction that would take
so#e data 'ro# the current row and 4 'ind 4 the previous and next rows data2 This
worked0 .ut introduce large overhead into .oth the develop#ent o' the 5uery and the
run-ti#e execution o' the 5uery2
;sing analytic 'unctions0 this is easy and e''icient to do2
set ecCo on
column de"tno &ormat (( Ceading +e"
column ename &ormat a' Ceading *name
column Ciredate Ceading =ired
column lastICire Ceading /ast=ired
column daysIlast Ceading +ays/ast
column ne!tICire Ceading 6e!t=ire
column daysIne!t Ceading 6e!t+ays
#rea$ on de"tno s$i" %
,*/*C. de"tno, ename, Ciredate,
L5(@iAedate,2,#ULL)
OF*- (PA-.5.5O6 BH de"tno
O-+*- BH Ciredate, ename) lastICire,
Ciredate - /A7(Ciredate,%,6>//)
OF*- (PA-.5.5O6 BH de"tno
O-+*- BH Ciredate, ename) daysIlast,
LED(@iAedate,2,#ULL)
OF*- (PA-.5.5O6 BH de"tno
O-+*- BH Ciredate, ename) ne!tICire,
/*A+(Ciredate,%,6>//)
OF*- (PA-.5.5O6 BH de"tno
O-+*- BH Ciredate, ename) - Ciredate daysIne!t
F-O9 em"
O-+*- BH de"tno, Ciredate
E
+e" *name =ired /ast=ired +ays/ast 6e!t=ire 6e!t+ays
--- ------ --------- --------- -------- --------- --------
%1 C/A-0 1736U#3;2 %8-6OF-;% %'%
0567 %8-6OF-;% 1736U#3;2 %'% 0*36#3;0 '8
95//*- 0*36#3;0 %8-6OF-;% '8
21 ,95.= %8-+*C-;1 12-AP--;% %1'
<O6*, 12-AP--;% %8-+*C-;1 %1' 1:-+*C-;% 234
FO-+ 1:-+*C-;% 12-AP--;% 234 1(-+*C-;2 :8%
,CO.. 1(-+*C-;2 1:-+*C-;% :8% %2-<A6-;: :3
A+A9, %2-<A6-;: 1(-+*C-;2 :3
:1 A//*6 21-F*B-;% 22-F*B-;% 2
WA-+ 22-F*B-;% 21-F*B-;% 2 1%-9AH-;% ';
B/A0* 1%-9AH-;% 22-F*B-;% '; 1;-,*P-;% %:1
.>-6*- 1;-,*P-;% 1%-9AH-;% %:1 2;-,*P-;% 21
9A-.56 2;-,*P-;% 1;-,*P-;% 21 1:-+*C-;% ''
<A9*, 1:-+*C-;% 2;-,*P-;% ''
The )"A+ and )A* routines could .e considered a way to 4 index into your partitioned
group 42 ;sing these 'unctions you can access any individual row2 otice 'or exa#ple in
the a.ove printout0 it shows that the record 'or DI* includes the data >in +old red
'ont? 'ro# the prior row >)AST HI&"? and the next row >"LT-HI&"?2 We can access the
'ields in records preceding or 'ollowing the current record in an ordered partition easily2
7A3
L5 ( BalueIe!"r J, o&&setK J, de&aultK )
OVER ( J)ueryI"artitionIclauseK orderI#yIclause )
)A* provides access to #ore than one row o' a ta.le at the sa#e ti#e without a sel(
8oin2 *iven a series o' rows returned 'ro# a 5uery and a position o' the cursor0 )A*
provides access to a row at a given physical o''set &rior to that position2
I' you do not speci'y "//se0 then its de'ault is $2 The optional de/a(l value is returned i'
the o''set goes .eyond the scope o' the window2 I' you do not speci'y de/a(l0 then its
de'ault value is null2
The 'ollowing exa#ple provides0 'or each person in the "6/ ta.le0 the salary o' the
e#ployee hired :ust .e'oreA
,*/*C. ename,Ciredate,sal,
L5(sal, 2, 1)
OVER (ORDER BY @iAedate) S !AeBSal
F-O9 em"
W=*-* Lo# @ AC/*-0AM
*name =ired ,A/ P-*F,A/
------ --------- ----- -------
,95.= %8-+*C-;1 ;11 1
<A9*, 1:-+*C-;% (41 ;11
95//*- 2:-<A6-;2 %:11 (41
A+A9, %2-<A6-;: %%11 %:11
7%A/
LED ( BalueIe!"r J, o&&setK J, de&aultK )
OVER ( J)ueryI"artitionIclauseK orderI#yIclause )
)"A+ provides access to #ore than one row o' a ta.le at the sa#e ti#e without a sel(
8oin2 *iven a series o' rows returned 'ro# a 5uery and a position o' the cursor0 )"A+
provides access to a row at a given physical o''set +eyond that position2
I' you do not speci'y o''set0 then its de'ault is $2 The optional de'ault value is returned i'
the o''set goes .eyond the scope o' the ta.le2 I' you do not speci'y de'ault0 then its
de'ault value is null2
The 'ollowing exa#ple provides0 'or each e#ployee in the "6/ ta.le0 the hire date o' the
e#ployee hired :ust a'terA
,*/*C. ename, Ciredate,
LED(@iAedate, 2)
OVER (ORDER BY @iAedate) S #eDt+iAed
F-O9 em" W=*-* de"tno @ :1M
*name =ired 6*N.=5-*+
------ --------- ---------
A//*6 21-F*B-;% 22-F*B-;%
WA-+ 22-F*B-;% 1%-9AH-;%
B/A0* 1%-9AH-;% 1;-,*P-;%
.>-6*- 1;-,*P-;% 2;-,*P-;%
9A-.56 2;-,*P-;% 1:-+*C-;%
<A9*, 1:-+*C-;%
/eter!ine the First 9alue : 7ast 9alue o( a 3rou&
The FI&STC,A);" and )ASTC,A);" 'unctions allow you to select the 'irst and last rows
'ro# a group2 These rows are especially valua.le .ecause they are o'ten used as the
.aselines in calculations2
%xa!&le
The 'ollowing exa#ple selects0 'or each e#ployee in each depart#ent0 the na#e o' the
e#ployee with the lowest salary2
#rea$ on de"tno s$i" %
,*/*C. de"tno, ename, sal,
'"RST%VLUE(ename)
OF*- (PA-.5.5O6 BH de"tno
O-+*- BH sal SC) A, 956I,A/I=A,
F-O9 em"
O-+*- BH de"tno, enameM
+*P.6O *6A9* ,A/ 956I,A/I=A,
---------- ---------- ---------- -----------
%1 C/A-0 2341 95//*-
0567 4111 95//*-
M"LLER 2*11 95//*-
21 A+A9, %%11 ,95.=
FO-+ :111 ,95.=
<O6*, 2(84 ,95.=
,CO.. :111 ,95.=
SM"T+ ;11 ,95.=
:1 A//*6 %'11 <A9*,
B/A0* 2;41 <A9*,
6MES 791 <A9*,
9A-.56 %241 <A9*,
.>-6*- %411 <A9*,
WA-+ %241 <A9*,
The 'ollowing exa#ple selects0 'or each e#ployee in each depart#ent0 the na#e o' the
e#ployee with the highest salary2
,*/*C. de"tno, ename, sal,
'"RST%VLUE(ename)
OF*- (PA-.5.5O6 BH de"tno
O-+*- BH sal DESC) A, 9ANI,A/I=A,
F-O9 em"
O-+*- BH de"tno, enameM
+*P.6O *6A9* ,A/ 9ANI,A/I=A,
---------- ---------- ---------- -----I-----
%1 C/A-0 2341 0567
."#5 9111 0567
95//*- %:11 0567
21 A+A9, %%11 FO-+
'ORD *111 FO-+
<O6*, 2(84 FO-+
,CO.. :111 FO-+
,95.= ;11 FO-+
:1 A//*6 %'11 B/A0*
BL.E 0;91 B/A0*
<A9*, (41 B/A0*
9A-.56 %241 B/A0*
.>-6*- %411 B/A0*
WA-+ %241 B/A0*
The 'ollowing exa#ple selects0 'or each e#ployee in depart#ent =< the na#e o' the
e#ployee with the lowest salary using an inline view
,*/*C. de"tno, ename, sal,
'"RST%VLUE(ename)
OF*- (O-+*- BH sal A,C) A, 956I,A/I=A,
F-O9 (SELECT ) 'ROM emp $+ERE deptno - *1)
+*P.6O *6A9* ,A/ 956I,A/I=A,
---------- ---------- ---------- -----------
:1 <A9*, (41 <A9*,
9A-.56 %241 <A9*,
WA-+ %241 <A9*,
.>-6*- %411 <A9*,
A//*6 %'11 <A9*,
B/A0* 2;41 <A9*,
Crossta+ or #ivot "ueries
A crossta+ )uery0 so#eti#es known as a &ivot )uery0 groups your data in a slightly
di''erent way 'ro# those we have seen hitherto2 A crossta. 5uery can .e used to get a
result with three rows >one 'or each pro:ect?0 with each row having three colu#ns >the
'irst listing the pro:ects and then one colu#n 'or each year? -- like thisA
ProLect 211% 2112
5+ C=F C=F
-------------------------------
%11 %2:.11 2:3.41
211 43:.11 2:1.11
:11 2:;.11 %21.41
"xa#ple
)etBs say you want to show the top = salary earners in each depart#ent as 0"l($!s% The
5uery needs to return exactly $ row per depart#ent and the row would have J colu#ns2
The +"/TO0 the na#e o' the highest paid e#ployee in the depart#ent0 the na#e o'
the next highest paid0 and so on2 ;sing analytic 'unctions this al#ost easy0 without
analytic 'unctions this was virtually i#possi.le2
SELECT deptno,
ME(DECODE(se&,2,ename,null)) FiAst,
ME(DECODE(se&,0,ename,null)) se/ond,
ME(DECODE(se&,*,ename,null)) t@iAd
'ROM (SELECT deptno, ename,
Ao?%numGeA()
OVER (!RT"T"O# BY deptno
ORDER BY sal des/ #ULLS LST) se&
'ROM emp)
$+ERE se& ,- *
5ROU! BY deptno
(
+*P.6O F5-,. ,*CO6+ .=5-+
---------- ---------- ---------- ----------
%1 0567 C/A-0 95//*-
21 ,CO.. FO-+ <O6*,
:1 B/A0* A//*6 .>-6*-
ote the inner 5uery0 that assigned a se5uence >&owr? to each e#ployee .y
depart#ent nu#.er in order o' salary2
,*/*C. de"tno, ename, sal,
roInum#er()
OF*- (PA-.5.5O6 BH de"tno
O-+*- BH sal desc 6>//, /A,.) -o6r
F-O9 em"M
+*P.6O *6A9* ,A/ -OW6-
---------- ---------- ---------- ----------
%1 0567 4111 %
%1 C/A-0 2341 2
%1 95//*- %:11 :
21 ,CO.. :111 %
21 FO-+ :111 2
21 <O6*, 2(84 :
21 A+A9, %%11 3
21 ,95.= ;11 4
:1 B/A0* 2;41 %
:1 A//*6 %'11 2
:1 .>-6*- %411 :
:1 WA-+ %241 3
:1 9A-.56 %241 4
:1 <A9*, (41 '
The +"CO+" in the outer 5uery keeps only rows with se5uences $0 % or = and assigns
the# to the correct 4colu#n42 The *&O;/ 9( gets rid o' the redundant rows and we are
le't with our collapsed result2 It #ay .e easier to understand i' you see the resultset
without the aggregate 'unction 6AL grouped .y deptno2
SELECT deptno,
DECODE(se&,2,ename,null) FiAst,
DECODE(se&,0,ename,null) se/ond,
DECODE(se&,*,ename,null) t@iAd
'ROM (SELECT deptno, ename,
Ao?%numGeA()
OVER (!RT"T"O# BY deptno
ORDER BY sal des/ #ULLS LST) se&
'ROM emp)
$+ERE se& ,- *
(
+*P.6O F5-,. ,*CO6+ .=5-+
---------- ---------- ---------- ----------
%1 0567
%1 C/A-0
%1 95//*-
21 ,CO..
21 FO-+
21 <O6*,
:1 B/A0*
:1 A//*6
:1 .>-6*-
The 6AL aggregate 'unction will .e applied .y the *&O;/ 9( colu#n +"/TO2 In any
given +"/TO a.ove only one row will have a non-null value 'or FI&ST0 the re#aining
rows in that group will always .e ;))2 The 6AL 'unction will pick out the non-null row
and keep that 'or us2 Hence0 the group .y and 6AL will collapse our resultset0 re#oving
the ;)) values 'ro# it and giving us what we want2
Conclusion
This new set o' 'unctionality holds so#e exiting possi.ilities2 It opens up a whole new
way o' looking at the data2 It will re#ove a lot o' procedural code and co#plex or
ine''icient 5ueries that would have taken a long to#e to develop0 to achieve the sa#e
result2
7inks and /ocu!ents
Further articles a.out Analytic Functions can .e 'ound inA
o OracleGi S!) &e'erence &elease $ >G2<2$?
o OracleGi +ata.ase Concepts &elease $ >G2<2$?
o OracleGi +ata Warehousing *uide &elease $ >G2<2$?

Вам также может понравиться