OVER clause in Oracle

SqlOracleWindow Functions

Sql Problem Overview


What is the meaning of the OVER clause in Oracle?

Sql Solutions


Solution 1 - Sql

The OVER clause specifies the partitioning, ordering and window "over which" the analytic function operates.

Example #1: calculate a moving average

AVG(amt) OVER (ORDER BY date ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)

date   amt   avg_amt
=====  ====  =======
1-Jan  10.0  10.5
2-Jan  11.0  17.0
3-Jan  30.0  17.0
4-Jan  10.0  18.0
5-Jan  14.0  12.0

It operates over a moving window (3 rows wide) over the rows, ordered by date.

Example #2: calculate a running balance

SUM(amt) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)

date   amt   sum_amt
=====  ====  =======
1-Jan  10.0  10.0
2-Jan  11.0  21.0
3-Jan  30.0  51.0
4-Jan  10.0  61.0
5-Jan  14.0  75.0

It operates over a window that includes the current row and all prior rows.

Note: for an aggregate with an OVER clause specifying a sort ORDER, the default window is UNBOUNDED PRECEDING to CURRENT ROW, so the above expression may be simplified to, with the same result:

SUM(amt) OVER (ORDER BY date)

Example #3: calculate the maximum within each group

MAX(amt) OVER (PARTITION BY dept)

dept  amt   max_amt
====  ====  =======
ACCT   5.0   7.0
ACCT   7.0   7.0
ACCT   6.0   7.0
MRKT  10.0  11.0
MRKT  11.0  11.0
SLES   2.0   2.0

It operates over a window that includes all rows for a particular dept.

SQL Fiddle: http://sqlfiddle.com/#!4/9eecb7d/122

Solution 2 - Sql

You can use it to transform some aggregate functions into analytic:

SELECT  MAX(date)
FROM    mytable

will return 1 row with a single maximum,

SELECT  MAX(date) OVER (ORDER BY id)
FROM    mytable

will return all rows with a running maximum.

Solution 3 - Sql

It's part of the Oracle analytic functions.

Solution 4 - Sql

Another way to use OVER is to have a result column in your select operate on another "partition", so to say.

This:

SELECT 
    name, 
    ssn, 
    case 
      when ( count(*) over (partition by ssn) ) > 1      
      then 1
      else 0
    end AS hasDuplicateSsn
FROM table;

returns 1 in hasDuplicateSsn for each row whose ssn is shared by another row. Great for making "tags" for data for different error reports and such.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionpaweloqueView Question on Stackoverflow
Solution 1 - SqlJeffrey KempView Answer on Stackoverflow
Solution 2 - SqlQuassnoiView Answer on Stackoverflow
Solution 3 - SqlcletusView Answer on Stackoverflow
Solution 4 - SqlstobixView Answer on Stackoverflow