SlideShare a Scribd company logo
The following is intended to outline our general product direction. It is intended for information purposes
only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code,
or functionality, and should not be relied upon in making purchasing decisions. The development,
release, timing, and pricing of any features or functionality described for Oracle’s products may change
and remains at the sole discretion of Oracle Corporation.
Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and
prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed
discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and
Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q
under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website
at http://www.oracle.com/investor. All information in this presentation is current as of September 2019
and Oracle undertakes no duty to update any statement in light of new information or future events.
Safe Harbor
Copyright © 2019 Oracle and/or its affiliates.
SQL Windowing Functions
Dave Stokes
MySQL Community Manager
Oracle Corporation
Copyright © 2019 Oracle and/or its affiliates.
Window Functions
Window functions allow access to data in
the records right before and after the
current record.
A window function defines a frame or
window of rows with a given length around
the current row, and performs a calculation
across the set of data in the window.
Copyright © 2019 Oracle and/or its affiliates.
https://en.wikipedia.org/wiki/SQL_window_function
Windowing Functions
MySQL 8.0 added support for window
functions.
However we will start with what doing
calculations WITHOUT WFs looked like!
Copyright © 2019 Oracle and/or its affiliates.
Sample Data – w/o WF
Copyright © 2019 Oracle and/or its affiliates.
SQL > select a,b,c,d from w1;
+---+----+-----+------+
| a | b | c | d |
+---+----+-----+------+
| 1 | 10 | 100 | 1000 |
| 2 | 20 | 200 | 2000 |
| 3 | 30 | 300 | 3000 |
| 4 | 40 | 400 | 4000 |
+---+----+-----+------+
4 rows in set (0.0004 sec)
Try to add rows -> Opps!
Copyright © 2019 Oracle and/or its affiliates.
select a,b,c,d, sum(a+b) as 'a&b' from w1;
+---+----+-----+------+-----+
| a | b | c | d | a&b |
+---+----+-----+------+-----+
| 1 | 10 | 100 | 1000 | 110 |
+---+----+-----+------+-----+
1 row in set (0.0028 sec)
1+2+3+4+10+20+30+40 = 110
Tell server how to ‘group’ data -> Better!
Copyright © 2019 Oracle and/or its affiliates.
select a,b,c,d, sum(a+b) as 'a&b'
from w1
GROUP BY a;
+---+----+-----+------+-----+
| a | b | c | d | a&b |
+---+----+-----+------+-----+
| 1 | 10 | 100 | 1000 | 11 |
| 2 | 20 | 200 | 2000 | 22 |
| 3 | 30 | 300 | 3000 | 33 |
| 4 | 40 | 400 | 4000 | 44 |
+---+----+-----+------+-----+
4 rows in set (0.0019 sec)
We can sum columns but …
Copyright © 2019 Oracle and/or its affiliates.
select a, sum(a), b, sum(b) from w1;
+---+--------+----+--------+
| a | sum(a) | b | sum(b) |
+---+--------+----+--------+
| 1 | 10 | 10 | 100 |
+---+--------+----+--------+
We can sum the first value
from a row and the sum of
all ‘a’ values. But does that
first value really tell us
anything?
1+2+3+4 = 10
10+20+30+40 = 100
New Data
Copyright © 2019 Oracle and/or its affiliates.
SQL > select id, price, warehouse, vendor
from w2;
+----+-------+-----------+--------+
| id | price | warehouse | vendor |
+----+-------+-----------+--------+
| 1 | 1.99 | 1 | 1 |
| 2 | 10.50 | 1 | 2 |
| 3 | 0.99 | 2 | 2 |
| 4 | 1.10 | 1 | 2 |
+----+-------+-----------+--------+
Grouping and Rollup
Copyright © 2019 Oracle and/or its affiliates.
select warehouse,
sum(price)
from w2
group by warehouse WITH ROLLUP;
+-----------+------------+
| warehouse | sum(price) |
+-----------+------------+
| 1 | 13.59 |
| 2 | 0.99 |
| NULL | 14.58 |
+-----------+------------+
We can group like items
together and even ‘roll up’
values for totals.
The NULL under the
warehouse column is the
ROLLUP or total of the
sum(price) -- And not easily
understood
And we can use different columns
Copyright © 2019 Oracle and/or its affiliates.
SQL > select vendor,
sum(price)
from w2
group by vendor with rollup;
+--------+------------+
| vendor | sum(price) |
+--------+------------+
| 1 | 1.99 |
| 2 | 12.59 |
| NULL | 14.58 |
+--------+------------+
Non Windowing Aggregate Functions
• SUM
• COUNT
• MAX,MIN,
• STD, STDDEV,STDDEV_POP, STDDEV_SAMP
• VAR,VAR_POP, VARIANCE
• See https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_sum
Copyright © 2019 Oracle and/or its affiliates.
So Why Windowing Functions
A window function performs an aggregate-like operation
on a set of query rows. However, whereas an aggregate
operation groups query rows into a single result row, a
window function produces a result for each query row:
• The row for which function evaluation occurs is called
the current row.
• The query rows related to the current row over which
function evaluation occurs comprise the window for the
current row.
Copyright © 2019 Oracle and/or its affiliates.
Warning!
Windowing Functions are difficult – you need
to practice with them to build understanding
and competence.
Do not panic if you struggle at first – they are
a learned skilled.
Copyright © 2019 Oracle and/or its affiliates.
NULL
Null (or NULL) is a special marker used in Structured Query
Language to indicate that a data value does not exist in the
database. Introduced by the creator of the relational database model,
E. F. Codd, SQL Null serves to fulfil the requirement that all true
relational database management systems (RDBMS) support a
representation of "missing information and inapplicable information“
https://en.wikipedia.org/wiki/Null_(SQL)
Copyright © 2019 Oracle and/or its affiliates.
New Keyword - OVER
Copyright © 2019 Oracle and/or its affiliates.
SELECT year, country, product, profit,
SUM(profit) OVER() AS total_profit,
SUM(profit) OVER(PARTITION BY country) AS country_profit
FROM sales
ORDER BY country, year, product, profit;
+------+---------+------------+--------+--------------+----------------+
| year | country | product | profit | total_profit | country_profit |
+------+---------+------------+--------+--------------+----------------+
| 2000 | Finland | Computer | 1500 | 7535 | 1610 | 1610 = 1500+100+10 (Finland)
| 2000 | Finland | Phone | 100 | 7535 | 1610 |
| 2001 | Finland | Phone | 10 | 7535 | 1610 |
| 2000 | India | Calculator | 75 | 7535 | 1350 |
| 2000 | India | Calculator | 75 | 7535 | 1350 |
| 2000 | India | Computer | 1200 | 7535 | 1350 |
| 2000 | USA | Calculator | 75 | 7535 | 4575 |
| 2000 | USA | Computer | 1500 | 7535 | 4575 |
| 2001 | USA | Calculator | 50 | 7535 | 4575 |
| 2001 | USA | Computer | 1200 | 7535 | 4575 |
| 2001 | USA | Computer | 1500 | 7535 | 4575 |
| 2001 | USA | TV | 100 | 7535 | 4575 |
| 2001 | USA | TV | 150 | 7535 | 4575 |
+------+---------+------------+--------+--------------+----------------+
= 7535
New Keyword - OVER
Copyright © 2019 Oracle and/or its affiliates.
SELECT year, country, product, profit,
SUM(profit) OVER() AS total_profit,
SUM(profit) OVER(PARTITION BY country) AS country_profit
FROM sales
ORDER BY country, year, product, profit;
The first OVER() clause is empty which treats the entire set of rows as a
partition (global).
The second OVER() clause partitions rows by country, producing a sum per
partition (per country). The function produces this sum for each partition
row (country).
Supported Non Aggregate Functions
• CUME_DIST()
• DENSE_RANK()
• FIRST_VALUE()
• LAG(), LEAD()
• LAST_VALUE()
• NTH_VALUE()
• NTILE()
• PERCENT_RANK()
• RANK()
• ROW_NUMBER()
Copyright © 2019 Oracle and/or its affiliates.
ROW_NUMBER()
Copyright © 2019 Oracle and/or its affiliates.
SQL > select
ROW_NUMBER() over () as 'row nbr', b
FROM w1;
+---------+----+
| row nbr | b |
+---------+----+
| 1 | 10 |
| 2 | 20 |
| 3 | 30 |
| 4 | 40 |
+---------+----+
Rank and Dense Rank
Copyright © 2019 Oracle and/or its affiliates.
SELECT x, row_number() over (order by x) AS 'Row Nbr',
rank() over (order by x) AS 'Rank',
DENSE_RANK() over (order by x) as 'Dense Rank'
from w4;
+---+---------+------+------------+
| x | Row Nbr | Rank | Dense Rank |
+---+---------+------+------------+
| 0 | 1 | 1 | 1 |
| 0 | 2 | 1 | 1 |
| 2 | 3 | 3 | 2 |
| 3 | 4 | 4 | 3 |
| 3 | 5 | 4 | 3 |
| 4 | 6 | 6 | 4 |
+---+---------+------+------------+
+---+
| x |
+---+
| 0 |
| 0 |
| 2 |
| 3 |
| 3 |
| 4 |
+---+
Rank and Dense Rank – Messy repeat
Copyright © 2019 Oracle and/or its affiliates.
SELECT x, row_number() over (order by x) AS 'Row Nbr',
rank() over (order by x) AS 'Rank',
DENSE_RANK() over (order by x) as 'Dense Rank'
from w4;
+---+---------+------+------------+
| x | Row Nbr | Rank | Dense Rank |
+---+---------+------+------------+
| 0 | 1 | 1 | 1 |
| 0 | 2 | 1 | 1 |
| 2 | 3 | 3 | 2 |
| 3 | 4 | 4 | 3 |
| 3 | 5 | 4 | 3 |
| 4 | 6 | 6 | 4 |
+---+---------+------+------------+
+---+
| x |
+---+
| 0 |
| 0 |
| 2 |
| 3 |
| 3 |
| 4 |
+---+
Rank and Dense Rank – Named Window
Copyright © 2019 Oracle and/or its affiliates.
SELECT x, ROW_NUMBER() over w AS 'Row Nbr',
RANK() over w AS 'Rank',
DENSE_RANK() over w as 'Dense Rank'
from w4
WINDOW w as (order by x);
+---+---------+------+------------+
| x | Row Nbr | Rank | Dense Rank |
+---+---------+------+------------+
| 0 | 1 | 1 | 1 |
| 0 | 2 | 1 | 1 |
| 2 | 3 | 3 | 2 |
| 3 | 4 | 4 | 3 |
| 3 | 5 | 4 | 3 |
| 4 | 6 | 6 | 4 |
+---+---------+------+------------+
+---+
| x |
+---+
| 0 |
| 0 |
| 2 |
| 3 |
| 3 |
| 4 |
+---+
You Can Modify Window Clauses
Copyright © 2019 Oracle and/or its affiliates.
SELECT DISTINCT year,
country,
FIRST_VALUE(year) OVER (w ORDER BY year ASC) AS first,
FIRST_VALUE(year) OVER (w ORDER BY year DESC) AS last
FROM sales
WINDOW w AS (PARTITION BY country);
What if you double up?
select date,
name,
first_value(date) over (w order by name) as first
from sales
window w as (order by date);
ERROR: 3583: Window '<unnamed window>' cannot inherit 'w'
since both contain an ORDER BY clause.
Copyright © 2019 Oracle and/or its affiliates.
Another Data Set
Copyright © 2019 Oracle and/or its affiliates.
select * from sales;
+------+------------+-------+
| name | date | sales |
+------+------------+-------+
| Dave | 2019-01-01 | 125 |
| Jack | 2019-01-15 | 86 |
| Lucy | 2019-01-13 | 140 |
| Dave | 2019-03-03 | 100 |
| Lucy | 2019-04-01 | 200 |
| Dave | 2019-09-01 | 100 |
| Jack | 2019-09-15 | 95 |
| Lucy | 2019-09-13 | 140 |
| Jack | 2019-06-03 | 100 |
| Lucy | 2019-05-01 | 200 |
+------+------------+-------+
It is often common to want to know the
sales by name, calendar dates, ranges
of prices, and etcetera.
Another Data Set
Copyright © 2019 Oracle and/or its affiliates.
select * from sales;
+------+------------+-------+
| name | date | sales |
+------+------------+-------+
| Dave | 2019-01-01 | 125 |
| Jack | 2019-01-15 | 86 |
| Lucy | 2019-01-13 | 140 |
| Dave | 2019-03-03 | 100 |
| Lucy | 2019-04-01 | 200 |
| Dave | 2019-09-01 | 100 |
| Jack | 2019-09-15 | 95 |
| Lucy | 2019-09-13 | 140 |
| Jack | 2019-06-03 | 100 |
| Lucy | 2019-05-01 | 200 |
+------+------------+-------+
SELECT name,
sum(sales)
from sales
group by name;
+------+------------+
| name | sum(sales) |
+------+------------+
| Dave | 325 |
| Jack | 281 |
| Lucy | 680 |
+------+------------+
Another Data Set
Copyright © 2019 Oracle and/or its affiliates.
select * from sales;
+------+------------+-------+
| name | date | sales |
+------+------------+-------+
| Dave | 2019-01-01 | 125 |
| Jack | 2019-01-15 | 86 |
| Lucy | 2019-01-13 | 140 |
| Dave | 2019-03-03 | 100 |
| Lucy | 2019-04-01 | 200 |
| Dave | 2019-09-01 | 100 |
| Jack | 2019-09-15 | 95 |
| Lucy | 2019-09-13 | 140 |
| Jack | 2019-06-03 | 100 |
| Lucy | 2019-05-01 | 200 |
+------+------------+-------+
select name, date, sales,
SUM(sales) OVER (partition by name) as 'sum'
FROM sales;
+------+------------+-------+-----+
| name | date | sales | sum |
+------+------------+-------+-----+
| Dave | 2019-01-01 | 125 | 325 |
| Dave | 2019-03-03 | 100 | 325 |
| Dave | 2019-09-01 | 100 | 325 |
| Jack | 2019-01-15 | 86 | 281 |
| Jack | 2019-09-15 | 95 | 281 |
| Jack | 2019-06-03 | 100 | 281 |
| Lucy | 2019-01-13 | 140 | 680 |
| Lucy | 2019-04-01 | 200 | 680 |
| Lucy | 2019-09-13 | 140 | 680 |
| Lucy | 2019-05-01 | 200 | 680 |
+------+------------+-------+-----+
Monthly results
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, MONTHNAME(date), sales,
sum(sales) OVER (PARTITION BY MONTH(date)) as 'my sum'
FROM sales;
+------+-----------------+-------+--------+
| name | MONTHNAME(date) | sales | my sum |
+------+-----------------+-------+--------+
| Dave | January | 125 | 351 |
| Jack | January | 86 | 351 |
| Lucy | January | 140 | 351 |
| Dave | March | 100 | 100 |
| Lucy | April | 200 | 200 |
| Lucy | May | 200 | 200 |
| Jack | June | 100 | 100 |
| Dave | September | 100 | 335 |
| Jack | September | 95 | 335 |
| Lucy | September | 140 | 335 |
+------+-----------------+-------+--------+
Cumulative Sales by name
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, sales, date,
SUM(sales) OVER (PARTITION by name ORDER BY date) as cum_sales
FROM sales;
+------+-------+------------+-----------+
| name | sales | date | cum_sales |
+------+-------+------------+-----------+
| Dave | 125 | 2019-01-01 | 125 |
| Dave | 100 | 2019-03-03 | 225 |
| Dave | 100 | 2019-09-01 | 325 |
| Jack | 86 | 2019-01-15 | 86 |
| Jack | 100 | 2019-06-03 | 186 |
| Jack | 95 | 2019-09-15 | 281 |
| Lucy | 140 | 2019-01-13 | 140 |
| Lucy | 200 | 2019-04-01 | 340 |
| Lucy | 200 | 2019-05-01 | 540 |
| Lucy | 140 | 2019-09-13 | 680 |
+------+-------+------------+-----------+
Current, N, and Unbounded Rows
Copyright © 2019 Oracle and/or its affiliates.
Cumulative Sales by sale
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, sales, date,
sum(sales) over (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
as cum_sales
FROM sales;
+------+-------+------------+-----------+
| name | sales | date | cum_sales |
+------+-------+------------+-----------+
| Dave | 125 | 2019-01-01 | 125 | 125
| Lucy | 140 | 2019-01-13 | 265 | 125+140 = 265
| Jack | 86 | 2019-01-15 | 351 | 265 + 86 = 351
| Dave | 100 | 2019-03-03 | 451 |
| Lucy | 200 | 2019-04-01 | 651 |
| Lucy | 200 | 2019-05-01 | 851 |
| Jack | 100 | 2019-06-03 | 951 |
| Dave | 100 | 2019-09-01 | 1051 |
| Lucy | 140 | 2019-09-13 | 1191 |
| Jack | 95 | 2019-09-15 | 1286 |
+------+-------+------------+-----------+
Average Sales
Copyright © 2019 Oracle and/or its affiliates.
SELECT MONTH(date), SUM(sales),
AVG(SUM(sales)) OVER (ORDER BY MONTH(date) RANGE BETWEEN 1 PRECEDING and 1 FOLLOWING)
AS slidingAvg from sales group by MONTH(date);
+-------------+------------+------------+
| MONTH(date) | SUM(sales) | slidingAvg |
+-------------+------------+------------+
| 1 | 351 | 351.0000 | 351
| 3 | 100 | 150.0000 | 150 = (351+100) / 3
| 4 | 200 | 166.6667 | 166.6667 = (100+200+200) / 3
| 5 | 200 | 166.6667 |
| 6 | 100 | 150.0000 |
| 9 | 335 | 335.0000 |
+-------------+------------+------------+
Another Data Set
Copyright © 2019 Oracle and/or its affiliates.
select * from sales;
+------+------------+-------+
| name | date | sales |
+------+------------+-------+
| Dave | 2019-01-01 | 125 |
| Jack | 2019-01-15 | 86 |
| Lucy | 2019-01-13 | 140 |
| Dave | 2019-03-03 | 100 |
| Lucy | 2019-04-01 | 200 |
| Dave | 2019-09-01 | 100 |
| Jack | 2019-09-15 | 95 |
| Lucy | 2019-09-13 | 140 |
| Jack | 2019-06-03 | 100 |
| Lucy | 2019-05-01 | 200 |
+------+------------+-------+
select name, date, sales,
SUM(sales) OVER w as 'sum'
FROM sales
WINDOW w AS (partition by name order by date);
+------+------------+-------+-----+
| name | date | sales | sum |
+------+------------+-------+-----+
| Dave | 2019-01-01 | 125 | 125 |
| Dave | 2019-03-03 | 100 | 225 |
| Dave | 2019-09-01 | 100 | 325 |
| Jack | 2019-01-15 | 86 | 86 |
| Jack | 2019-06-03 | 100 | 186 |
| Jack | 2019-09-15 | 95 | 281 |
| Lucy | 2019-01-13 | 140 | 140 |
| Lucy | 2019-04-01 | 200 | 340 |
| Lucy | 2019-05-01 | 200 | 540 |
| Lucy | 2019-09-13 | 140 | 680 |
+------+------------+-------+-----+
Syntax
Copyright © 2019 Oracle and/or its affiliates.
over_clause:
{OVER (window_spec) | OVER window_name}
window_spec:
[window_name] [partition_clause] [order_clause]
[frame_clause]
partition_clause:
PARTITION BY expr [, expr] ...
order_clause:
ORDER BY expr [ASC|DESC] [, expr [ASC|DESC]] ...
Syntax
Copyright © 2019 Oracle and/or its affiliates.
frame_clause: frame_units frame_extent
frame_units: {ROWS | RANGE}
frame_extent:
{frame_start | frame_between}
frame_between:
BETWEEN frame_start AND frame_end frame_start, frame_end:
{ CURRENT ROW | UNBOUNDED PRECEDING | UNBOUNDED FOLLOWING |
expr PRECEDING | expr FOLLOWING }
Lets work a simple average w/ default
Copyright © 2019 Oracle and/or its affiliates.
select a, count(a) over w as 'count a',
b, avg(b) over w as 'avg b' from w1
window w as (order by a) ;
+---+---------+----+---------+
| a | count a | b | avg b |
+---+---------+----+---------+
| 1 | 1 | 10 | 10.0000 |
| 2 | 2 | 20 | 15.0000 | 15 = (10+20)/2
| 3 | 3 | 30 | 20.0000 | 30 = (10+20+30)/3
| 4 | 4 | 40 | 25.0000 | 25 = 100/4
+---+---------+----+---------+ Default is UNBOUNDED
PRECEDING to CURRENT
ROWS BETWEEN
Copyright © 2019 Oracle and/or its affiliates.
select a, count(a) over w as 'count a',
b, avg(b) over w as 'avg b' from w1
window w as
(ROWS BETWEEN 1 PRECEDING and CURRENT ROW) ;
+---+---------+----+---------+
| a | count a | b | avg b |
+---+---------+----+---------+
| 1 | 1 | 10 | 10.0000 |
| 2 | 2 | 20 | 15.0000 |
| 3 | 2 | 30 | 25.0000 | 25 = (20+30) / 2
| 4 | 2 | 40 | 35.0000 | 35 = (30+40) / 2
ROWS BETWEEN
Copyright © 2019 Oracle and/or its affiliates.
select a, count(a) over w as 'count a',
b, avg(b) over w as 'avg b' from w1
window w as
(ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) ;
+---+---------+----+---------+
| a | count a | b | avg b |
+---+---------+----+---------+
| 1 | 1 | 10 | 10.0000 |
| 2 | 2 | 20 | 15.0000 |
| 3 | 3 | 30 | 20.0000 |
| 4 | 4 | 40 | 25.0000 |
ROWS BETWEEN
Copyright © 2019 Oracle and/or its affiliates.
select a, count(a) over w as 'count a',
b, avg(b) over w as 'avg b' from w1
window w as (PARTITION BY a >= 3) ;
+---+---------+----+---------+
| a | count a | b | avg b |
+---+---------+----+---------+
| 1 | 2 | 10 | 15.0000 | 15 = (10+20)/2
| 2 | 2 | 20 | 15.0000 |
| 3 | 2 | 30 | 35.0000 | Start of PARTITION
| 4 | 2 | 40 | 35.0000 | 35 = (30+40)/2
LAG – values from preceding (x) rows
Copyright © 2019 Oracle and/or its affiliates.
select a, lag(a,1) over w as 'lag(1)',
lag(a,2) over w as 'lag(2)' from w1
window w as (order by a);
+---+--------+--------+
| a | lag(1) | lag(2) |
+---+--------+--------+
| 1 | NULL | NULL |
| 2 | 1 | NULL |
| 3 | 2 | 1 |
| 4 | 3 | 2 |
+---+--------+--------+
LEAD – values from preceding (x) rows
Copyright © 2019 Oracle and/or its affiliates.
select a, lead(a,1) over w as 'lead(1)',
lead(a,2) over w as 'lead(2)' from w1
window w as (order by a);
+---+---------+---------+
| a | lead(1) | lead(2) |
+---+---------+---------+
| 1 | 2 | 3 |
| 2 | 3 | 4 |
| 3 | 4 | NULL |
| 4 | NULL | NULL |
First and Last Values
Copyright © 2019 Oracle and/or its affiliates.
select a, FIRST_VALUE(a) over w as 'first value',
LAST_VALUE(a) over w as 'last value'
from w1 window w as (order by a);
+---+-------------+------------+
| a | first value | last value |
+---+-------------+------------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 1 | 4 |
N Values
Copyright © 2019 Oracle and/or its affiliates.
select a,
NTH_VALUE(a,2) over w as 'n2',
NTH_VALUE(a,3) over w as 'n3' from w1 window w as
(order by a);
+---+------+------+
| a | n2 | n3 |
+---+------+------+
| 1 | NULL | NULL | No 2nd or 3rd row read so no values
| 2 | 2 | NULL | No 3rd row read so no values
| 3 | 2 | 3 |
| 4 | 2 | 3 |
Another Example
Copyright © 2019 Oracle and/or its affiliates.
SELECT * FROM staff ORDER by id;
+----+-------+-----------+---------+
| id | name | dept | salary |
+----+-------+-----------+---------+
| 1 | Andy | Shipping | 5400.00 |
| 2 | Betty | Marketing | 6300.00 |
| 3 | Tracy | Shipping | 4800.00 |
| 4 | Mike | Marketing | 7100.00 |
| 5 | Sandy | Sales | 5400.00 |
| 6 | James | Shipping | 6000.00 |
| 7 | Carol | Sales | 4600.00 |
Another Example
Copyright © 2019 Oracle and/or its affiliates.
SELECT COUNT(*), SUM(salary) FROM staff;
+----------+-------------+
| COUNT(*) | SUM(salary) |
+----------+-------------+
| 7 | 39600.00 |
+----------+-------------+
Another Example
Copyright © 2019 Oracle and/or its affiliates.
SELECT COUNT(*) AS 'nbr' ,
SUM(salary) as 'tot salary',
ROUND(avg(salary),0) AS avg
FROM staff
GROUP BY dept ORDER BY dept;
+-----+------------+------+
| nbr | tot salary | avg |
+-----+------------+------+
| 2 | 13400.00 | 6700 |
| 2 | 10000.00 | 5000 |
| 3 | 16200.00 | 5400 |
Another Example
Copyright © 2019 Oracle and/or its affiliates.
SELECT dept, COUNT(*) AS 'nbr' ,
SUM(salary) as 'tot salary',
ROUND(avg(salary),0) AS avg
FROM staff
GROUP BY dept WITH ROLLUP order by dept;
+-----------+-----+------------+------+
| dept | nbr | tot salary | avg |
+-----------+-----+------------+------+
| NULL | 7 | 39600.00 | 5657 |
| Marketing | 2 | 13400.00 | 6700 |
| Sales | 2 | 10000.00 | 5000 |
| Shipping | 3 | 16200.00 | 5400 |
Another Example
Copyright © 2019 Oracle and/or its affiliates.
SELECT dept, COUNT(*) AS 'nbr' ,
SUM(salary) as 'tot salary',
ROUND(avg(salary),0) AS avg
FROM staff
GROUP BY dept WITH ROLLUP order by dept;
+-----------+-----+------------+------+
| dept | nbr | tot salary | avg |
+-----------+-----+------------+------+
| NULL | 7 | 39600.00 | 5657 |
| Marketing | 2 | 13400.00 | 6700 |
| Sales | 2 | 10000.00 | 5000 |
| Shipping | 3 | 16200.00 | 5400 |
Calculate Rank
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, salary,
RANK() OVER s AS 'Rank' ,
DENSE_RANK() OVER s AS ‘Dense Rank'
FROM staff
WINDOW s as (ORDER BY salary DESC) ;
+-------+---------+------+-------------+
| name | salary | Rank | Dense Rank |
+-------+---------+------+-------------+
| Mike | 7100.00 | 1 | 1 |
| Betty | 6300.00 | 2 | 2 |
| James | 6000.00 | 3 | 3 |
| Sandy | 5400.00 | 4 | 4 |
| Andy | 5400.00 | 4 | 4 |
| Tracy | 4800.00 | 6 | 5 |
| Carol | 4600.00 | 7 | 6 |
Percentage of Total Salary
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, salary,
ROUND(salary / SUM(salary) OVER() * 100,2) AS '%'
FROM staff ORDER BY salary DESC;
+-------+---------+-------+
| name | salary | % |
+-------+---------+-------+
| Mike | 7100.00 | 17.93 |
| Betty | 6300.00 | 15.91 |
| James | 6000.00 | 15.15 |
| Andy | 5400.00 | 13.64 |
| Sandy | 5400.00 | 13.64 |
| Tracy | 4800.00 | 12.12 |
| Carol | 4600.00 | 11.62 |
Difference to AVG Salary
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, salary,
ROUND(AVG(salary) OVER (),2) AS 'avg',
ROUND(salary - AVG(salary) OVER (),2) AS 'Diff to AVG'
FROM staff ORDER BY salary DESC;
+-------+---------+---------+-------------+
| name | salary | avg | Diff to AVG |
+-------+---------+---------+-------------+
| Mike | 7100.00 | 5657.14 | 1442.86 |
| Betty | 6300.00 | 5657.14 | 642.86 |
| James | 6000.00 | 5657.14 | 342.86 |
| Andy | 5400.00 | 5657.14 | -257.14 |
| Sandy | 5400.00 | 5657.14 | -257.14 |
| Tracy | 4800.00 | 5657.14 | -857.14 |
| Carol | 4600.00 | 5657.14 | -1057.14 |
Calculate differences in salary
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, salary,
salary - LEAD(salary,1) OVER (ORDER BY salary DESC) as 'diff next'
FROM staff ORDER BY salary DESC;
+-------+---------+-----------+
| name | salary | diff next |
+-------+---------+-----------+
| Mike | 7100.00 | 800.00 |
| Betty | 6300.00 | 300.00 |
| James | 6000.00 | 600.00 |
| Andy | 5400.00 | 0.00 |
| Sandy | 5400.00 | 600.00 |
| Tracy | 4800.00 | 200.00 |
| Carol | 4600.00 | NULL |
Calculate differences in salary
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, salary,
salary - LAST_VALUE(salary) OVER w AS 'above',
ROUND((salary - LAST_VALUE(salary) OVER w) / LAST_VALUE(salary)
OVER w * 100) AS 'pct above'
FROM staff
WINDOW w as (ORDER by salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND
UNBOUNDED FOLLOWING) ORDER BY salary DESC;
+-------+---------+---------+-----------+
| name | salary | above | pct above |
+-------+---------+---------+-----------+
| Mike | 7100.00 | 2500.00 | 54 |
| Betty | 6300.00 | 1700.00 | 37 |
| James | 6000.00 | 1400.00 | 30 |
| Sandy | 5400.00 | 800.00 | 17 |
| Andy | 5400.00 | 800.00 | 17 |
| Tracy | 4800.00 | 200.00 | 4 |
| Carol | 4600.00 | 0.00 | 0 |
Calculate differences in salary
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, dept, salary,
round(AVG(salary) OVER z,2) AS 'Avg',
round(salary - AVG(salary) OVER z,2) as 'diff avg'
FROM staff WINDOW z AS (PARTITION BY dept)
ORDER BY dept, salary DESC;
+-------+-----------+---------+---------+----------+
| name | dept | salary | Avg | diff avg |
+-------+-----------+---------+---------+----------+
| Mike | Marketing | 7100.00 | 6700.00 | 400.00 |
| Betty | Marketing | 6300.00 | 6700.00 | -400.00 |
| Sandy | Sales | 5400.00 | 5000.00 | 400.00 |
| Carol | Sales | 4600.00 | 5000.00 | -400.00 |
| James | Shipping | 6000.00 | 5400.00 | 600.00 |
| Andy | Shipping | 5400.00 | 5400.00 | 0.00 |
| Tracy | Shipping | 4800.00 | 5400.00 | -600.00 |
Company and Departmental Ranks
Copyright © 2019 Oracle and/or its affiliates.
SELECT name, dept, salary,
RANK() OVER s AS dept_rank,
RANK() OVER (ORDER BY salary DESC) AS Company_rank
FROM staff
WINDOW s as (PARTITION BY dept ORDER BY salary DESC)
ORDER BY dept, salary DESC;
+-------+-----------+---------+-----------+--------------+
| name | dept | salary | dept_rank | Company_rank |
+-------+-----------+---------+-----------+--------------+
| Mike | Marketing | 7100.00 | 1 | 1 |
| Betty | Marketing | 6300.00 | 2 | 2 |
| Sandy | Sales | 5400.00 | 1 | 4 |
| Carol | Sales | 4600.00 | 2 | 7 |
| James | Shipping | 6000.00 | 1 | 3 |
| Andy | Shipping | 5400.00 | 2 | 4 |
| Tracy | Shipping | 4800.00 | 3 | 6 |
Good Place to Stop .. for now.
Copyright © 2019 Oracle and/or its affiliates.
Excellent Tutorial on Windowing Functions
https://momjian.us/main/writings/pgsql/window.pdf
Copyright © 2019 Oracle and/or its affiliates.
MySQL Windowing Functions
https://dev.mysql.com/doc/refman/8.0/en/window-functions.html
Copyright © 2019 Oracle and/or its affiliates.
Please buy my Book!
Copyright © 2019 Oracle and/or its affiliates.
Q/A
Copyright © 2019 Oracle and/or its affiliates.
Slides at Slideshare.net/davidmstokes
Email at David.Stokes @ Oracle.com
Blog at https://elephantdolphin.blogspot.com/

More Related Content

Similar to Windowing Functions - Little Rock Tech Fest 2019

SQL window functions for MySQL
SQL window functions for MySQLSQL window functions for MySQL
SQL window functions for MySQL
Dag H. Wanvik
 
Five more things about Oracle SQL and PLSQL
Five more things about Oracle SQL and PLSQLFive more things about Oracle SQL and PLSQL
Five more things about Oracle SQL and PLSQL
Connor McDonald
 
Oracle Exadata Cloud Services guide from practical experience - OOW19
Oracle Exadata Cloud Services guide from practical experience - OOW19Oracle Exadata Cloud Services guide from practical experience - OOW19
Oracle Exadata Cloud Services guide from practical experience - OOW19
Nelson Calero
 
Oracle Database features every developer should know about
Oracle Database features every developer should know aboutOracle Database features every developer should know about
Oracle Database features every developer should know about
gvenzl
 
Short Intro to PHP and MySQL
Short Intro to PHP and MySQLShort Intro to PHP and MySQL
Short Intro to PHP and MySQLJussi Pohjolainen
 
Using Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query PerformanceUsing Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query Performance
oysteing
 
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleUnderstanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Guatemala User Group
 
Oracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor formatOracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor format
Franck Pachot
 
Rethinking SQL for Big Data with Apache Drill
Rethinking SQL for Big Data with Apache DrillRethinking SQL for Big Data with Apache Drill
Rethinking SQL for Big Data with Apache Drill
MapR Technologies
 
May Woo Bi Portfolio
May Woo Bi PortfolioMay Woo Bi Portfolio
May Woo Bi Portfoliomaywoo
 
Five_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptx
Five_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptxFive_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptx
Five_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptx
Maria Colgan
 
Optimizer percona live_ams2015
Optimizer percona live_ams2015Optimizer percona live_ams2015
Optimizer percona live_ams2015
Manyi Lu
 
Explain
ExplainExplain
More than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12cMore than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12c
Guatemala User Group
 
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
Dave Stokes
 
SAP BO ONLINE TRAINING
SAP BO ONLINE TRAININGSAP BO ONLINE TRAINING
SAP BO ONLINE TRAINING
TRAINING ICON
 
Sap bo online training
Sap bo online trainingSap bo online training
Sap bo online training
TRAINING ICON
 
Impala 2.0 Update #impalajp
Impala 2.0 Update #impalajpImpala 2.0 Update #impalajp
Impala 2.0 Update #impalajp
Cloudera Japan
 
The State of the Dolphin, MySQL Keynote at Percona Live Europe 2019, Amsterda...
The State of the Dolphin, MySQL Keynote at Percona Live Europe 2019, Amsterda...The State of the Dolphin, MySQL Keynote at Percona Live Europe 2019, Amsterda...
The State of the Dolphin, MySQL Keynote at Percona Live Europe 2019, Amsterda...Geir Høydalsvik
 
Window functions
Window functionsWindow functions
Window functions
Davide Dell'Erba
 

Similar to Windowing Functions - Little Rock Tech Fest 2019 (20)

SQL window functions for MySQL
SQL window functions for MySQLSQL window functions for MySQL
SQL window functions for MySQL
 
Five more things about Oracle SQL and PLSQL
Five more things about Oracle SQL and PLSQLFive more things about Oracle SQL and PLSQL
Five more things about Oracle SQL and PLSQL
 
Oracle Exadata Cloud Services guide from practical experience - OOW19
Oracle Exadata Cloud Services guide from practical experience - OOW19Oracle Exadata Cloud Services guide from practical experience - OOW19
Oracle Exadata Cloud Services guide from practical experience - OOW19
 
Oracle Database features every developer should know about
Oracle Database features every developer should know aboutOracle Database features every developer should know about
Oracle Database features every developer should know about
 
Short Intro to PHP and MySQL
Short Intro to PHP and MySQLShort Intro to PHP and MySQL
Short Intro to PHP and MySQL
 
Using Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query PerformanceUsing Optimizer Hints to Improve MySQL Query Performance
Using Optimizer Hints to Improve MySQL Query Performance
 
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ OracleUnderstanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
Understanding Query Optimization with ‘regular’ and ‘Exadata’ Oracle
 
Oracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor formatOracle dbms_xplan.display_cursor format
Oracle dbms_xplan.display_cursor format
 
Rethinking SQL for Big Data with Apache Drill
Rethinking SQL for Big Data with Apache DrillRethinking SQL for Big Data with Apache Drill
Rethinking SQL for Big Data with Apache Drill
 
May Woo Bi Portfolio
May Woo Bi PortfolioMay Woo Bi Portfolio
May Woo Bi Portfolio
 
Five_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptx
Five_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptxFive_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptx
Five_Things_You_Might_Not_Know_About_Oracle_Database_v2.pptx
 
Optimizer percona live_ams2015
Optimizer percona live_ams2015Optimizer percona live_ams2015
Optimizer percona live_ams2015
 
Explain
ExplainExplain
Explain
 
More than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12cMore than 12 More things about Oracle Database 12c
More than 12 More things about Oracle Database 12c
 
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
MySQL 8.0 Features -- Oracle CodeOne 2019, All Things Open 2019
 
SAP BO ONLINE TRAINING
SAP BO ONLINE TRAININGSAP BO ONLINE TRAINING
SAP BO ONLINE TRAINING
 
Sap bo online training
Sap bo online trainingSap bo online training
Sap bo online training
 
Impala 2.0 Update #impalajp
Impala 2.0 Update #impalajpImpala 2.0 Update #impalajp
Impala 2.0 Update #impalajp
 
The State of the Dolphin, MySQL Keynote at Percona Live Europe 2019, Amsterda...
The State of the Dolphin, MySQL Keynote at Percona Live Europe 2019, Amsterda...The State of the Dolphin, MySQL Keynote at Percona Live Europe 2019, Amsterda...
The State of the Dolphin, MySQL Keynote at Percona Live Europe 2019, Amsterda...
 
Window functions
Window functionsWindow functions
Window functions
 

More from Dave Stokes

Json within a relational database
Json within a relational databaseJson within a relational database
Json within a relational database
Dave Stokes
 
Database basics for new-ish developers -- All Things Open October 18th 2021
Database basics for new-ish developers  -- All Things Open October 18th 2021Database basics for new-ish developers  -- All Things Open October 18th 2021
Database basics for new-ish developers -- All Things Open October 18th 2021
Dave Stokes
 
Php &amp; my sql - how do pdo, mysq-li, and x devapi do what they do
Php &amp; my sql  - how do pdo, mysq-li, and x devapi do what they doPhp &amp; my sql  - how do pdo, mysq-li, and x devapi do what they do
Php &amp; my sql - how do pdo, mysq-li, and x devapi do what they do
Dave Stokes
 
Longhorn PHP - MySQL Indexes, Histograms, Locking Options, and Other Ways to ...
Longhorn PHP - MySQL Indexes, Histograms, Locking Options, and Other Ways to ...Longhorn PHP - MySQL Indexes, Histograms, Locking Options, and Other Ways to ...
Longhorn PHP - MySQL Indexes, Histograms, Locking Options, and Other Ways to ...
Dave Stokes
 
MySQL 8.0 New Features -- September 27th presentation for Open Source Summit
MySQL 8.0 New Features -- September 27th presentation for Open Source SummitMySQL 8.0 New Features -- September 27th presentation for Open Source Summit
MySQL 8.0 New Features -- September 27th presentation for Open Source Summit
Dave Stokes
 
JavaScript and Friends August 20th, 20201 -- MySQL Shell and JavaScript
JavaScript and Friends August 20th, 20201 -- MySQL Shell and JavaScriptJavaScript and Friends August 20th, 20201 -- MySQL Shell and JavaScript
JavaScript and Friends August 20th, 20201 -- MySQL Shell and JavaScript
Dave Stokes
 
Open Source World June '21 -- JSON Within a Relational Database
Open Source World June '21 -- JSON Within a Relational DatabaseOpen Source World June '21 -- JSON Within a Relational Database
Open Source World June '21 -- JSON Within a Relational Database
Dave Stokes
 
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and HistogramsDutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
Dave Stokes
 
Validating JSON -- Percona Live 2021 presentation
Validating JSON -- Percona Live 2021 presentationValidating JSON -- Percona Live 2021 presentation
Validating JSON -- Percona Live 2021 presentation
Dave Stokes
 
Midwest PHP Presentation - New MSQL Features
Midwest PHP Presentation - New MSQL FeaturesMidwest PHP Presentation - New MSQL Features
Midwest PHP Presentation - New MSQL Features
Dave Stokes
 
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Dave Stokes
 
Confoo 2021 -- MySQL New Features
Confoo 2021 -- MySQL New FeaturesConfoo 2021 -- MySQL New Features
Confoo 2021 -- MySQL New Features
Dave Stokes
 
Confoo 2021 - MySQL Indexes & Histograms
Confoo 2021 - MySQL Indexes & HistogramsConfoo 2021 - MySQL Indexes & Histograms
Confoo 2021 - MySQL Indexes & Histograms
Dave Stokes
 
Datacon LA - MySQL without the SQL - Oh my!
Datacon LA - MySQL without the SQL - Oh my! Datacon LA - MySQL without the SQL - Oh my!
Datacon LA - MySQL without the SQL - Oh my!
Dave Stokes
 
MySQL Replication Update - DEbconf 2020 presentation
MySQL Replication Update - DEbconf 2020 presentationMySQL Replication Update - DEbconf 2020 presentation
MySQL Replication Update - DEbconf 2020 presentation
Dave Stokes
 
MySQL 8.0 Operational Changes
MySQL 8.0 Operational ChangesMySQL 8.0 Operational Changes
MySQL 8.0 Operational Changes
Dave Stokes
 
cPanel now supports MySQL 8.0 - My Top Seven Features
cPanel now supports MySQL 8.0 - My Top Seven FeaturescPanel now supports MySQL 8.0 - My Top Seven Features
cPanel now supports MySQL 8.0 - My Top Seven Features
Dave Stokes
 
A Step by Step Introduction to the MySQL Document Store
A Step by Step Introduction to the MySQL Document StoreA Step by Step Introduction to the MySQL Document Store
A Step by Step Introduction to the MySQL Document Store
Dave Stokes
 
Discover The Power of NoSQL + MySQL with MySQL
Discover The Power of NoSQL + MySQL with MySQLDiscover The Power of NoSQL + MySQL with MySQL
Discover The Power of NoSQL + MySQL with MySQL
Dave Stokes
 
Discover the Power of the NoSQL + SQL with MySQL
Discover the Power of the NoSQL + SQL with MySQLDiscover the Power of the NoSQL + SQL with MySQL
Discover the Power of the NoSQL + SQL with MySQL
Dave Stokes
 

More from Dave Stokes (20)

Json within a relational database
Json within a relational databaseJson within a relational database
Json within a relational database
 
Database basics for new-ish developers -- All Things Open October 18th 2021
Database basics for new-ish developers  -- All Things Open October 18th 2021Database basics for new-ish developers  -- All Things Open October 18th 2021
Database basics for new-ish developers -- All Things Open October 18th 2021
 
Php &amp; my sql - how do pdo, mysq-li, and x devapi do what they do
Php &amp; my sql  - how do pdo, mysq-li, and x devapi do what they doPhp &amp; my sql  - how do pdo, mysq-li, and x devapi do what they do
Php &amp; my sql - how do pdo, mysq-li, and x devapi do what they do
 
Longhorn PHP - MySQL Indexes, Histograms, Locking Options, and Other Ways to ...
Longhorn PHP - MySQL Indexes, Histograms, Locking Options, and Other Ways to ...Longhorn PHP - MySQL Indexes, Histograms, Locking Options, and Other Ways to ...
Longhorn PHP - MySQL Indexes, Histograms, Locking Options, and Other Ways to ...
 
MySQL 8.0 New Features -- September 27th presentation for Open Source Summit
MySQL 8.0 New Features -- September 27th presentation for Open Source SummitMySQL 8.0 New Features -- September 27th presentation for Open Source Summit
MySQL 8.0 New Features -- September 27th presentation for Open Source Summit
 
JavaScript and Friends August 20th, 20201 -- MySQL Shell and JavaScript
JavaScript and Friends August 20th, 20201 -- MySQL Shell and JavaScriptJavaScript and Friends August 20th, 20201 -- MySQL Shell and JavaScript
JavaScript and Friends August 20th, 20201 -- MySQL Shell and JavaScript
 
Open Source World June '21 -- JSON Within a Relational Database
Open Source World June '21 -- JSON Within a Relational DatabaseOpen Source World June '21 -- JSON Within a Relational Database
Open Source World June '21 -- JSON Within a Relational Database
 
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and HistogramsDutch PHP Conference 2021 - MySQL Indexes and Histograms
Dutch PHP Conference 2021 - MySQL Indexes and Histograms
 
Validating JSON -- Percona Live 2021 presentation
Validating JSON -- Percona Live 2021 presentationValidating JSON -- Percona Live 2021 presentation
Validating JSON -- Percona Live 2021 presentation
 
Midwest PHP Presentation - New MSQL Features
Midwest PHP Presentation - New MSQL FeaturesMidwest PHP Presentation - New MSQL Features
Midwest PHP Presentation - New MSQL Features
 
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
Open Source 1010 and Quest InSync presentations March 30th, 2021 on MySQL Ind...
 
Confoo 2021 -- MySQL New Features
Confoo 2021 -- MySQL New FeaturesConfoo 2021 -- MySQL New Features
Confoo 2021 -- MySQL New Features
 
Confoo 2021 - MySQL Indexes & Histograms
Confoo 2021 - MySQL Indexes & HistogramsConfoo 2021 - MySQL Indexes & Histograms
Confoo 2021 - MySQL Indexes & Histograms
 
Datacon LA - MySQL without the SQL - Oh my!
Datacon LA - MySQL without the SQL - Oh my! Datacon LA - MySQL without the SQL - Oh my!
Datacon LA - MySQL without the SQL - Oh my!
 
MySQL Replication Update - DEbconf 2020 presentation
MySQL Replication Update - DEbconf 2020 presentationMySQL Replication Update - DEbconf 2020 presentation
MySQL Replication Update - DEbconf 2020 presentation
 
MySQL 8.0 Operational Changes
MySQL 8.0 Operational ChangesMySQL 8.0 Operational Changes
MySQL 8.0 Operational Changes
 
cPanel now supports MySQL 8.0 - My Top Seven Features
cPanel now supports MySQL 8.0 - My Top Seven FeaturescPanel now supports MySQL 8.0 - My Top Seven Features
cPanel now supports MySQL 8.0 - My Top Seven Features
 
A Step by Step Introduction to the MySQL Document Store
A Step by Step Introduction to the MySQL Document StoreA Step by Step Introduction to the MySQL Document Store
A Step by Step Introduction to the MySQL Document Store
 
Discover The Power of NoSQL + MySQL with MySQL
Discover The Power of NoSQL + MySQL with MySQLDiscover The Power of NoSQL + MySQL with MySQL
Discover The Power of NoSQL + MySQL with MySQL
 
Discover the Power of the NoSQL + SQL with MySQL
Discover the Power of the NoSQL + SQL with MySQLDiscover the Power of the NoSQL + SQL with MySQL
Discover the Power of the NoSQL + SQL with MySQL
 

Recently uploaded

Internet-Security-Safeguarding-Your-Digital-World (1).pptx
Internet-Security-Safeguarding-Your-Digital-World (1).pptxInternet-Security-Safeguarding-Your-Digital-World (1).pptx
Internet-Security-Safeguarding-Your-Digital-World (1).pptx
VivekSinghShekhawat2
 
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
ufdana
 
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
eutxy
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
laozhuseo02
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
3ipehhoa
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
Rogerio Filho
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
laozhuseo02
 
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptxBridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Brad Spiegel Macon GA
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Sanjeev Rampal
 
test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
Arif0071
 
Latest trends in computer networking.pptx
Latest trends in computer networking.pptxLatest trends in computer networking.pptx
Latest trends in computer networking.pptx
JungkooksNonexistent
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
Gal Baras
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
3ipehhoa
 
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
3ipehhoa
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
nirahealhty
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
JeyaPerumal1
 
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdfJAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
Javier Lasa
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
natyesu
 
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
keoku
 
Comptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guideComptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guide
GTProductions1
 

Recently uploaded (20)

Internet-Security-Safeguarding-Your-Digital-World (1).pptx
Internet-Security-Safeguarding-Your-Digital-World (1).pptxInternet-Security-Safeguarding-Your-Digital-World (1).pptx
Internet-Security-Safeguarding-Your-Digital-World (1).pptx
 
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
一比一原版(CSU毕业证)加利福尼亚州立大学毕业证成绩单专业办理
 
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
一比一原版(LBS毕业证)伦敦商学院毕业证成绩单专业办理
 
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shopHistory+of+E-commerce+Development+in+China-www.cfye-commerce.shop
History+of+E-commerce+Development+in+China-www.cfye-commerce.shop
 
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
1比1复刻(bath毕业证书)英国巴斯大学毕业证学位证原版一模一样
 
guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...guildmasters guide to ravnica Dungeons & Dragons 5...
guildmasters guide to ravnica Dungeons & Dragons 5...
 
The+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptxThe+Prospects+of+E-Commerce+in+China.pptx
The+Prospects+of+E-Commerce+in+China.pptx
 
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptxBridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
Bridging the Digital Gap Brad Spiegel Macon, GA Initiative.pptx
 
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and GuidelinesMulti-cluster Kubernetes Networking- Patterns, Projects and Guidelines
Multi-cluster Kubernetes Networking- Patterns, Projects and Guidelines
 
test test test test testtest test testtest test testtest test testtest test ...
test test  test test testtest test testtest test testtest test testtest test ...test test  test test testtest test testtest test testtest test testtest test ...
test test test test testtest test testtest test testtest test testtest test ...
 
Latest trends in computer networking.pptx
Latest trends in computer networking.pptxLatest trends in computer networking.pptx
Latest trends in computer networking.pptx
 
How to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptxHow to Use Contact Form 7 Like a Pro.pptx
How to Use Contact Form 7 Like a Pro.pptx
 
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
原版仿制(uob毕业证书)英国伯明翰大学毕业证本科学历证书原版一模一样
 
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
急速办(bedfordhire毕业证书)英国贝德福特大学毕业证成绩单原版一模一样
 
This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!This 7-second Brain Wave Ritual Attracts Money To You.!
This 7-second Brain Wave Ritual Attracts Money To You.!
 
1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...1.Wireless Communication System_Wireless communication is a broad term that i...
1.Wireless Communication System_Wireless communication is a broad term that i...
 
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdfJAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
JAVIER LASA-EXPERIENCIA digital 1986-2024.pdf
 
BASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptxBASIC C++ lecture NOTE C++ lecture 3.pptx
BASIC C++ lecture NOTE C++ lecture 3.pptx
 
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
一比一原版(SLU毕业证)圣路易斯大学毕业证成绩单专业办理
 
Comptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guideComptia N+ Standard Networking lesson guide
Comptia N+ Standard Networking lesson guide
 

Windowing Functions - Little Rock Tech Fest 2019

  • 1. The following is intended to outline our general product direction. It is intended for information purposes only, and may not be incorporated into any contract. It is not a commitment to deliver any material, code, or functionality, and should not be relied upon in making purchasing decisions. The development, release, timing, and pricing of any features or functionality described for Oracle’s products may change and remains at the sole discretion of Oracle Corporation. Statements in this presentation relating to Oracle’s future plans, expectations, beliefs, intentions and prospects are “forward-looking statements” and are subject to material risks and uncertainties. A detailed discussion of these factors and other risks that affect our business is contained in Oracle’s Securities and Exchange Commission (SEC) filings, including our most recent reports on Form 10-K and Form 10-Q under the heading “Risk Factors.” These filings are available on the SEC’s website or on Oracle’s website at http://www.oracle.com/investor. All information in this presentation is current as of September 2019 and Oracle undertakes no duty to update any statement in light of new information or future events. Safe Harbor Copyright © 2019 Oracle and/or its affiliates.
  • 2. SQL Windowing Functions Dave Stokes MySQL Community Manager Oracle Corporation Copyright © 2019 Oracle and/or its affiliates.
  • 3. Window Functions Window functions allow access to data in the records right before and after the current record. A window function defines a frame or window of rows with a given length around the current row, and performs a calculation across the set of data in the window. Copyright © 2019 Oracle and/or its affiliates. https://en.wikipedia.org/wiki/SQL_window_function
  • 4. Windowing Functions MySQL 8.0 added support for window functions. However we will start with what doing calculations WITHOUT WFs looked like! Copyright © 2019 Oracle and/or its affiliates.
  • 5. Sample Data – w/o WF Copyright © 2019 Oracle and/or its affiliates. SQL > select a,b,c,d from w1; +---+----+-----+------+ | a | b | c | d | +---+----+-----+------+ | 1 | 10 | 100 | 1000 | | 2 | 20 | 200 | 2000 | | 3 | 30 | 300 | 3000 | | 4 | 40 | 400 | 4000 | +---+----+-----+------+ 4 rows in set (0.0004 sec)
  • 6. Try to add rows -> Opps! Copyright © 2019 Oracle and/or its affiliates. select a,b,c,d, sum(a+b) as 'a&b' from w1; +---+----+-----+------+-----+ | a | b | c | d | a&b | +---+----+-----+------+-----+ | 1 | 10 | 100 | 1000 | 110 | +---+----+-----+------+-----+ 1 row in set (0.0028 sec) 1+2+3+4+10+20+30+40 = 110
  • 7. Tell server how to ‘group’ data -> Better! Copyright © 2019 Oracle and/or its affiliates. select a,b,c,d, sum(a+b) as 'a&b' from w1 GROUP BY a; +---+----+-----+------+-----+ | a | b | c | d | a&b | +---+----+-----+------+-----+ | 1 | 10 | 100 | 1000 | 11 | | 2 | 20 | 200 | 2000 | 22 | | 3 | 30 | 300 | 3000 | 33 | | 4 | 40 | 400 | 4000 | 44 | +---+----+-----+------+-----+ 4 rows in set (0.0019 sec)
  • 8. We can sum columns but … Copyright © 2019 Oracle and/or its affiliates. select a, sum(a), b, sum(b) from w1; +---+--------+----+--------+ | a | sum(a) | b | sum(b) | +---+--------+----+--------+ | 1 | 10 | 10 | 100 | +---+--------+----+--------+ We can sum the first value from a row and the sum of all ‘a’ values. But does that first value really tell us anything? 1+2+3+4 = 10 10+20+30+40 = 100
  • 9. New Data Copyright © 2019 Oracle and/or its affiliates. SQL > select id, price, warehouse, vendor from w2; +----+-------+-----------+--------+ | id | price | warehouse | vendor | +----+-------+-----------+--------+ | 1 | 1.99 | 1 | 1 | | 2 | 10.50 | 1 | 2 | | 3 | 0.99 | 2 | 2 | | 4 | 1.10 | 1 | 2 | +----+-------+-----------+--------+
  • 10. Grouping and Rollup Copyright © 2019 Oracle and/or its affiliates. select warehouse, sum(price) from w2 group by warehouse WITH ROLLUP; +-----------+------------+ | warehouse | sum(price) | +-----------+------------+ | 1 | 13.59 | | 2 | 0.99 | | NULL | 14.58 | +-----------+------------+ We can group like items together and even ‘roll up’ values for totals. The NULL under the warehouse column is the ROLLUP or total of the sum(price) -- And not easily understood
  • 11. And we can use different columns Copyright © 2019 Oracle and/or its affiliates. SQL > select vendor, sum(price) from w2 group by vendor with rollup; +--------+------------+ | vendor | sum(price) | +--------+------------+ | 1 | 1.99 | | 2 | 12.59 | | NULL | 14.58 | +--------+------------+
  • 12. Non Windowing Aggregate Functions • SUM • COUNT • MAX,MIN, • STD, STDDEV,STDDEV_POP, STDDEV_SAMP • VAR,VAR_POP, VARIANCE • See https://dev.mysql.com/doc/refman/8.0/en/group-by-functions.html#function_sum Copyright © 2019 Oracle and/or its affiliates.
  • 13. So Why Windowing Functions A window function performs an aggregate-like operation on a set of query rows. However, whereas an aggregate operation groups query rows into a single result row, a window function produces a result for each query row: • The row for which function evaluation occurs is called the current row. • The query rows related to the current row over which function evaluation occurs comprise the window for the current row. Copyright © 2019 Oracle and/or its affiliates.
  • 14. Warning! Windowing Functions are difficult – you need to practice with them to build understanding and competence. Do not panic if you struggle at first – they are a learned skilled. Copyright © 2019 Oracle and/or its affiliates.
  • 15. NULL Null (or NULL) is a special marker used in Structured Query Language to indicate that a data value does not exist in the database. Introduced by the creator of the relational database model, E. F. Codd, SQL Null serves to fulfil the requirement that all true relational database management systems (RDBMS) support a representation of "missing information and inapplicable information“ https://en.wikipedia.org/wiki/Null_(SQL) Copyright © 2019 Oracle and/or its affiliates.
  • 16. New Keyword - OVER Copyright © 2019 Oracle and/or its affiliates. SELECT year, country, product, profit, SUM(profit) OVER() AS total_profit, SUM(profit) OVER(PARTITION BY country) AS country_profit FROM sales ORDER BY country, year, product, profit; +------+---------+------------+--------+--------------+----------------+ | year | country | product | profit | total_profit | country_profit | +------+---------+------------+--------+--------------+----------------+ | 2000 | Finland | Computer | 1500 | 7535 | 1610 | 1610 = 1500+100+10 (Finland) | 2000 | Finland | Phone | 100 | 7535 | 1610 | | 2001 | Finland | Phone | 10 | 7535 | 1610 | | 2000 | India | Calculator | 75 | 7535 | 1350 | | 2000 | India | Calculator | 75 | 7535 | 1350 | | 2000 | India | Computer | 1200 | 7535 | 1350 | | 2000 | USA | Calculator | 75 | 7535 | 4575 | | 2000 | USA | Computer | 1500 | 7535 | 4575 | | 2001 | USA | Calculator | 50 | 7535 | 4575 | | 2001 | USA | Computer | 1200 | 7535 | 4575 | | 2001 | USA | Computer | 1500 | 7535 | 4575 | | 2001 | USA | TV | 100 | 7535 | 4575 | | 2001 | USA | TV | 150 | 7535 | 4575 | +------+---------+------------+--------+--------------+----------------+ = 7535
  • 17. New Keyword - OVER Copyright © 2019 Oracle and/or its affiliates. SELECT year, country, product, profit, SUM(profit) OVER() AS total_profit, SUM(profit) OVER(PARTITION BY country) AS country_profit FROM sales ORDER BY country, year, product, profit; The first OVER() clause is empty which treats the entire set of rows as a partition (global). The second OVER() clause partitions rows by country, producing a sum per partition (per country). The function produces this sum for each partition row (country).
  • 18. Supported Non Aggregate Functions • CUME_DIST() • DENSE_RANK() • FIRST_VALUE() • LAG(), LEAD() • LAST_VALUE() • NTH_VALUE() • NTILE() • PERCENT_RANK() • RANK() • ROW_NUMBER() Copyright © 2019 Oracle and/or its affiliates.
  • 19. ROW_NUMBER() Copyright © 2019 Oracle and/or its affiliates. SQL > select ROW_NUMBER() over () as 'row nbr', b FROM w1; +---------+----+ | row nbr | b | +---------+----+ | 1 | 10 | | 2 | 20 | | 3 | 30 | | 4 | 40 | +---------+----+
  • 20. Rank and Dense Rank Copyright © 2019 Oracle and/or its affiliates. SELECT x, row_number() over (order by x) AS 'Row Nbr', rank() over (order by x) AS 'Rank', DENSE_RANK() over (order by x) as 'Dense Rank' from w4; +---+---------+------+------------+ | x | Row Nbr | Rank | Dense Rank | +---+---------+------+------------+ | 0 | 1 | 1 | 1 | | 0 | 2 | 1 | 1 | | 2 | 3 | 3 | 2 | | 3 | 4 | 4 | 3 | | 3 | 5 | 4 | 3 | | 4 | 6 | 6 | 4 | +---+---------+------+------------+ +---+ | x | +---+ | 0 | | 0 | | 2 | | 3 | | 3 | | 4 | +---+
  • 21. Rank and Dense Rank – Messy repeat Copyright © 2019 Oracle and/or its affiliates. SELECT x, row_number() over (order by x) AS 'Row Nbr', rank() over (order by x) AS 'Rank', DENSE_RANK() over (order by x) as 'Dense Rank' from w4; +---+---------+------+------------+ | x | Row Nbr | Rank | Dense Rank | +---+---------+------+------------+ | 0 | 1 | 1 | 1 | | 0 | 2 | 1 | 1 | | 2 | 3 | 3 | 2 | | 3 | 4 | 4 | 3 | | 3 | 5 | 4 | 3 | | 4 | 6 | 6 | 4 | +---+---------+------+------------+ +---+ | x | +---+ | 0 | | 0 | | 2 | | 3 | | 3 | | 4 | +---+
  • 22. Rank and Dense Rank – Named Window Copyright © 2019 Oracle and/or its affiliates. SELECT x, ROW_NUMBER() over w AS 'Row Nbr', RANK() over w AS 'Rank', DENSE_RANK() over w as 'Dense Rank' from w4 WINDOW w as (order by x); +---+---------+------+------------+ | x | Row Nbr | Rank | Dense Rank | +---+---------+------+------------+ | 0 | 1 | 1 | 1 | | 0 | 2 | 1 | 1 | | 2 | 3 | 3 | 2 | | 3 | 4 | 4 | 3 | | 3 | 5 | 4 | 3 | | 4 | 6 | 6 | 4 | +---+---------+------+------------+ +---+ | x | +---+ | 0 | | 0 | | 2 | | 3 | | 3 | | 4 | +---+
  • 23. You Can Modify Window Clauses Copyright © 2019 Oracle and/or its affiliates. SELECT DISTINCT year, country, FIRST_VALUE(year) OVER (w ORDER BY year ASC) AS first, FIRST_VALUE(year) OVER (w ORDER BY year DESC) AS last FROM sales WINDOW w AS (PARTITION BY country);
  • 24. What if you double up? select date, name, first_value(date) over (w order by name) as first from sales window w as (order by date); ERROR: 3583: Window '<unnamed window>' cannot inherit 'w' since both contain an ORDER BY clause. Copyright © 2019 Oracle and/or its affiliates.
  • 25. Another Data Set Copyright © 2019 Oracle and/or its affiliates. select * from sales; +------+------------+-------+ | name | date | sales | +------+------------+-------+ | Dave | 2019-01-01 | 125 | | Jack | 2019-01-15 | 86 | | Lucy | 2019-01-13 | 140 | | Dave | 2019-03-03 | 100 | | Lucy | 2019-04-01 | 200 | | Dave | 2019-09-01 | 100 | | Jack | 2019-09-15 | 95 | | Lucy | 2019-09-13 | 140 | | Jack | 2019-06-03 | 100 | | Lucy | 2019-05-01 | 200 | +------+------------+-------+ It is often common to want to know the sales by name, calendar dates, ranges of prices, and etcetera.
  • 26. Another Data Set Copyright © 2019 Oracle and/or its affiliates. select * from sales; +------+------------+-------+ | name | date | sales | +------+------------+-------+ | Dave | 2019-01-01 | 125 | | Jack | 2019-01-15 | 86 | | Lucy | 2019-01-13 | 140 | | Dave | 2019-03-03 | 100 | | Lucy | 2019-04-01 | 200 | | Dave | 2019-09-01 | 100 | | Jack | 2019-09-15 | 95 | | Lucy | 2019-09-13 | 140 | | Jack | 2019-06-03 | 100 | | Lucy | 2019-05-01 | 200 | +------+------------+-------+ SELECT name, sum(sales) from sales group by name; +------+------------+ | name | sum(sales) | +------+------------+ | Dave | 325 | | Jack | 281 | | Lucy | 680 | +------+------------+
  • 27. Another Data Set Copyright © 2019 Oracle and/or its affiliates. select * from sales; +------+------------+-------+ | name | date | sales | +------+------------+-------+ | Dave | 2019-01-01 | 125 | | Jack | 2019-01-15 | 86 | | Lucy | 2019-01-13 | 140 | | Dave | 2019-03-03 | 100 | | Lucy | 2019-04-01 | 200 | | Dave | 2019-09-01 | 100 | | Jack | 2019-09-15 | 95 | | Lucy | 2019-09-13 | 140 | | Jack | 2019-06-03 | 100 | | Lucy | 2019-05-01 | 200 | +------+------------+-------+ select name, date, sales, SUM(sales) OVER (partition by name) as 'sum' FROM sales; +------+------------+-------+-----+ | name | date | sales | sum | +------+------------+-------+-----+ | Dave | 2019-01-01 | 125 | 325 | | Dave | 2019-03-03 | 100 | 325 | | Dave | 2019-09-01 | 100 | 325 | | Jack | 2019-01-15 | 86 | 281 | | Jack | 2019-09-15 | 95 | 281 | | Jack | 2019-06-03 | 100 | 281 | | Lucy | 2019-01-13 | 140 | 680 | | Lucy | 2019-04-01 | 200 | 680 | | Lucy | 2019-09-13 | 140 | 680 | | Lucy | 2019-05-01 | 200 | 680 | +------+------------+-------+-----+
  • 28. Monthly results Copyright © 2019 Oracle and/or its affiliates. SELECT name, MONTHNAME(date), sales, sum(sales) OVER (PARTITION BY MONTH(date)) as 'my sum' FROM sales; +------+-----------------+-------+--------+ | name | MONTHNAME(date) | sales | my sum | +------+-----------------+-------+--------+ | Dave | January | 125 | 351 | | Jack | January | 86 | 351 | | Lucy | January | 140 | 351 | | Dave | March | 100 | 100 | | Lucy | April | 200 | 200 | | Lucy | May | 200 | 200 | | Jack | June | 100 | 100 | | Dave | September | 100 | 335 | | Jack | September | 95 | 335 | | Lucy | September | 140 | 335 | +------+-----------------+-------+--------+
  • 29. Cumulative Sales by name Copyright © 2019 Oracle and/or its affiliates. SELECT name, sales, date, SUM(sales) OVER (PARTITION by name ORDER BY date) as cum_sales FROM sales; +------+-------+------------+-----------+ | name | sales | date | cum_sales | +------+-------+------------+-----------+ | Dave | 125 | 2019-01-01 | 125 | | Dave | 100 | 2019-03-03 | 225 | | Dave | 100 | 2019-09-01 | 325 | | Jack | 86 | 2019-01-15 | 86 | | Jack | 100 | 2019-06-03 | 186 | | Jack | 95 | 2019-09-15 | 281 | | Lucy | 140 | 2019-01-13 | 140 | | Lucy | 200 | 2019-04-01 | 340 | | Lucy | 200 | 2019-05-01 | 540 | | Lucy | 140 | 2019-09-13 | 680 | +------+-------+------------+-----------+
  • 30. Current, N, and Unbounded Rows Copyright © 2019 Oracle and/or its affiliates.
  • 31. Cumulative Sales by sale Copyright © 2019 Oracle and/or its affiliates. SELECT name, sales, date, sum(sales) over (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) as cum_sales FROM sales; +------+-------+------------+-----------+ | name | sales | date | cum_sales | +------+-------+------------+-----------+ | Dave | 125 | 2019-01-01 | 125 | 125 | Lucy | 140 | 2019-01-13 | 265 | 125+140 = 265 | Jack | 86 | 2019-01-15 | 351 | 265 + 86 = 351 | Dave | 100 | 2019-03-03 | 451 | | Lucy | 200 | 2019-04-01 | 651 | | Lucy | 200 | 2019-05-01 | 851 | | Jack | 100 | 2019-06-03 | 951 | | Dave | 100 | 2019-09-01 | 1051 | | Lucy | 140 | 2019-09-13 | 1191 | | Jack | 95 | 2019-09-15 | 1286 | +------+-------+------------+-----------+
  • 32. Average Sales Copyright © 2019 Oracle and/or its affiliates. SELECT MONTH(date), SUM(sales), AVG(SUM(sales)) OVER (ORDER BY MONTH(date) RANGE BETWEEN 1 PRECEDING and 1 FOLLOWING) AS slidingAvg from sales group by MONTH(date); +-------------+------------+------------+ | MONTH(date) | SUM(sales) | slidingAvg | +-------------+------------+------------+ | 1 | 351 | 351.0000 | 351 | 3 | 100 | 150.0000 | 150 = (351+100) / 3 | 4 | 200 | 166.6667 | 166.6667 = (100+200+200) / 3 | 5 | 200 | 166.6667 | | 6 | 100 | 150.0000 | | 9 | 335 | 335.0000 | +-------------+------------+------------+
  • 33. Another Data Set Copyright © 2019 Oracle and/or its affiliates. select * from sales; +------+------------+-------+ | name | date | sales | +------+------------+-------+ | Dave | 2019-01-01 | 125 | | Jack | 2019-01-15 | 86 | | Lucy | 2019-01-13 | 140 | | Dave | 2019-03-03 | 100 | | Lucy | 2019-04-01 | 200 | | Dave | 2019-09-01 | 100 | | Jack | 2019-09-15 | 95 | | Lucy | 2019-09-13 | 140 | | Jack | 2019-06-03 | 100 | | Lucy | 2019-05-01 | 200 | +------+------------+-------+ select name, date, sales, SUM(sales) OVER w as 'sum' FROM sales WINDOW w AS (partition by name order by date); +------+------------+-------+-----+ | name | date | sales | sum | +------+------------+-------+-----+ | Dave | 2019-01-01 | 125 | 125 | | Dave | 2019-03-03 | 100 | 225 | | Dave | 2019-09-01 | 100 | 325 | | Jack | 2019-01-15 | 86 | 86 | | Jack | 2019-06-03 | 100 | 186 | | Jack | 2019-09-15 | 95 | 281 | | Lucy | 2019-01-13 | 140 | 140 | | Lucy | 2019-04-01 | 200 | 340 | | Lucy | 2019-05-01 | 200 | 540 | | Lucy | 2019-09-13 | 140 | 680 | +------+------------+-------+-----+
  • 34. Syntax Copyright © 2019 Oracle and/or its affiliates. over_clause: {OVER (window_spec) | OVER window_name} window_spec: [window_name] [partition_clause] [order_clause] [frame_clause] partition_clause: PARTITION BY expr [, expr] ... order_clause: ORDER BY expr [ASC|DESC] [, expr [ASC|DESC]] ...
  • 35. Syntax Copyright © 2019 Oracle and/or its affiliates. frame_clause: frame_units frame_extent frame_units: {ROWS | RANGE} frame_extent: {frame_start | frame_between} frame_between: BETWEEN frame_start AND frame_end frame_start, frame_end: { CURRENT ROW | UNBOUNDED PRECEDING | UNBOUNDED FOLLOWING | expr PRECEDING | expr FOLLOWING }
  • 36. Lets work a simple average w/ default Copyright © 2019 Oracle and/or its affiliates. select a, count(a) over w as 'count a', b, avg(b) over w as 'avg b' from w1 window w as (order by a) ; +---+---------+----+---------+ | a | count a | b | avg b | +---+---------+----+---------+ | 1 | 1 | 10 | 10.0000 | | 2 | 2 | 20 | 15.0000 | 15 = (10+20)/2 | 3 | 3 | 30 | 20.0000 | 30 = (10+20+30)/3 | 4 | 4 | 40 | 25.0000 | 25 = 100/4 +---+---------+----+---------+ Default is UNBOUNDED PRECEDING to CURRENT
  • 37. ROWS BETWEEN Copyright © 2019 Oracle and/or its affiliates. select a, count(a) over w as 'count a', b, avg(b) over w as 'avg b' from w1 window w as (ROWS BETWEEN 1 PRECEDING and CURRENT ROW) ; +---+---------+----+---------+ | a | count a | b | avg b | +---+---------+----+---------+ | 1 | 1 | 10 | 10.0000 | | 2 | 2 | 20 | 15.0000 | | 3 | 2 | 30 | 25.0000 | 25 = (20+30) / 2 | 4 | 2 | 40 | 35.0000 | 35 = (30+40) / 2
  • 38. ROWS BETWEEN Copyright © 2019 Oracle and/or its affiliates. select a, count(a) over w as 'count a', b, avg(b) over w as 'avg b' from w1 window w as (ROWS BETWEEN UNBOUNDED PRECEDING and CURRENT ROW) ; +---+---------+----+---------+ | a | count a | b | avg b | +---+---------+----+---------+ | 1 | 1 | 10 | 10.0000 | | 2 | 2 | 20 | 15.0000 | | 3 | 3 | 30 | 20.0000 | | 4 | 4 | 40 | 25.0000 |
  • 39. ROWS BETWEEN Copyright © 2019 Oracle and/or its affiliates. select a, count(a) over w as 'count a', b, avg(b) over w as 'avg b' from w1 window w as (PARTITION BY a >= 3) ; +---+---------+----+---------+ | a | count a | b | avg b | +---+---------+----+---------+ | 1 | 2 | 10 | 15.0000 | 15 = (10+20)/2 | 2 | 2 | 20 | 15.0000 | | 3 | 2 | 30 | 35.0000 | Start of PARTITION | 4 | 2 | 40 | 35.0000 | 35 = (30+40)/2
  • 40. LAG – values from preceding (x) rows Copyright © 2019 Oracle and/or its affiliates. select a, lag(a,1) over w as 'lag(1)', lag(a,2) over w as 'lag(2)' from w1 window w as (order by a); +---+--------+--------+ | a | lag(1) | lag(2) | +---+--------+--------+ | 1 | NULL | NULL | | 2 | 1 | NULL | | 3 | 2 | 1 | | 4 | 3 | 2 | +---+--------+--------+
  • 41. LEAD – values from preceding (x) rows Copyright © 2019 Oracle and/or its affiliates. select a, lead(a,1) over w as 'lead(1)', lead(a,2) over w as 'lead(2)' from w1 window w as (order by a); +---+---------+---------+ | a | lead(1) | lead(2) | +---+---------+---------+ | 1 | 2 | 3 | | 2 | 3 | 4 | | 3 | 4 | NULL | | 4 | NULL | NULL |
  • 42. First and Last Values Copyright © 2019 Oracle and/or its affiliates. select a, FIRST_VALUE(a) over w as 'first value', LAST_VALUE(a) over w as 'last value' from w1 window w as (order by a); +---+-------------+------------+ | a | first value | last value | +---+-------------+------------+ | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 1 | 3 | | 4 | 1 | 4 |
  • 43. N Values Copyright © 2019 Oracle and/or its affiliates. select a, NTH_VALUE(a,2) over w as 'n2', NTH_VALUE(a,3) over w as 'n3' from w1 window w as (order by a); +---+------+------+ | a | n2 | n3 | +---+------+------+ | 1 | NULL | NULL | No 2nd or 3rd row read so no values | 2 | 2 | NULL | No 3rd row read so no values | 3 | 2 | 3 | | 4 | 2 | 3 |
  • 44. Another Example Copyright © 2019 Oracle and/or its affiliates. SELECT * FROM staff ORDER by id; +----+-------+-----------+---------+ | id | name | dept | salary | +----+-------+-----------+---------+ | 1 | Andy | Shipping | 5400.00 | | 2 | Betty | Marketing | 6300.00 | | 3 | Tracy | Shipping | 4800.00 | | 4 | Mike | Marketing | 7100.00 | | 5 | Sandy | Sales | 5400.00 | | 6 | James | Shipping | 6000.00 | | 7 | Carol | Sales | 4600.00 |
  • 45. Another Example Copyright © 2019 Oracle and/or its affiliates. SELECT COUNT(*), SUM(salary) FROM staff; +----------+-------------+ | COUNT(*) | SUM(salary) | +----------+-------------+ | 7 | 39600.00 | +----------+-------------+
  • 46. Another Example Copyright © 2019 Oracle and/or its affiliates. SELECT COUNT(*) AS 'nbr' , SUM(salary) as 'tot salary', ROUND(avg(salary),0) AS avg FROM staff GROUP BY dept ORDER BY dept; +-----+------------+------+ | nbr | tot salary | avg | +-----+------------+------+ | 2 | 13400.00 | 6700 | | 2 | 10000.00 | 5000 | | 3 | 16200.00 | 5400 |
  • 47. Another Example Copyright © 2019 Oracle and/or its affiliates. SELECT dept, COUNT(*) AS 'nbr' , SUM(salary) as 'tot salary', ROUND(avg(salary),0) AS avg FROM staff GROUP BY dept WITH ROLLUP order by dept; +-----------+-----+------------+------+ | dept | nbr | tot salary | avg | +-----------+-----+------------+------+ | NULL | 7 | 39600.00 | 5657 | | Marketing | 2 | 13400.00 | 6700 | | Sales | 2 | 10000.00 | 5000 | | Shipping | 3 | 16200.00 | 5400 |
  • 48. Another Example Copyright © 2019 Oracle and/or its affiliates. SELECT dept, COUNT(*) AS 'nbr' , SUM(salary) as 'tot salary', ROUND(avg(salary),0) AS avg FROM staff GROUP BY dept WITH ROLLUP order by dept; +-----------+-----+------------+------+ | dept | nbr | tot salary | avg | +-----------+-----+------------+------+ | NULL | 7 | 39600.00 | 5657 | | Marketing | 2 | 13400.00 | 6700 | | Sales | 2 | 10000.00 | 5000 | | Shipping | 3 | 16200.00 | 5400 |
  • 49. Calculate Rank Copyright © 2019 Oracle and/or its affiliates. SELECT name, salary, RANK() OVER s AS 'Rank' , DENSE_RANK() OVER s AS ‘Dense Rank' FROM staff WINDOW s as (ORDER BY salary DESC) ; +-------+---------+------+-------------+ | name | salary | Rank | Dense Rank | +-------+---------+------+-------------+ | Mike | 7100.00 | 1 | 1 | | Betty | 6300.00 | 2 | 2 | | James | 6000.00 | 3 | 3 | | Sandy | 5400.00 | 4 | 4 | | Andy | 5400.00 | 4 | 4 | | Tracy | 4800.00 | 6 | 5 | | Carol | 4600.00 | 7 | 6 |
  • 50. Percentage of Total Salary Copyright © 2019 Oracle and/or its affiliates. SELECT name, salary, ROUND(salary / SUM(salary) OVER() * 100,2) AS '%' FROM staff ORDER BY salary DESC; +-------+---------+-------+ | name | salary | % | +-------+---------+-------+ | Mike | 7100.00 | 17.93 | | Betty | 6300.00 | 15.91 | | James | 6000.00 | 15.15 | | Andy | 5400.00 | 13.64 | | Sandy | 5400.00 | 13.64 | | Tracy | 4800.00 | 12.12 | | Carol | 4600.00 | 11.62 |
  • 51. Difference to AVG Salary Copyright © 2019 Oracle and/or its affiliates. SELECT name, salary, ROUND(AVG(salary) OVER (),2) AS 'avg', ROUND(salary - AVG(salary) OVER (),2) AS 'Diff to AVG' FROM staff ORDER BY salary DESC; +-------+---------+---------+-------------+ | name | salary | avg | Diff to AVG | +-------+---------+---------+-------------+ | Mike | 7100.00 | 5657.14 | 1442.86 | | Betty | 6300.00 | 5657.14 | 642.86 | | James | 6000.00 | 5657.14 | 342.86 | | Andy | 5400.00 | 5657.14 | -257.14 | | Sandy | 5400.00 | 5657.14 | -257.14 | | Tracy | 4800.00 | 5657.14 | -857.14 | | Carol | 4600.00 | 5657.14 | -1057.14 |
  • 52. Calculate differences in salary Copyright © 2019 Oracle and/or its affiliates. SELECT name, salary, salary - LEAD(salary,1) OVER (ORDER BY salary DESC) as 'diff next' FROM staff ORDER BY salary DESC; +-------+---------+-----------+ | name | salary | diff next | +-------+---------+-----------+ | Mike | 7100.00 | 800.00 | | Betty | 6300.00 | 300.00 | | James | 6000.00 | 600.00 | | Andy | 5400.00 | 0.00 | | Sandy | 5400.00 | 600.00 | | Tracy | 4800.00 | 200.00 | | Carol | 4600.00 | NULL |
  • 53. Calculate differences in salary Copyright © 2019 Oracle and/or its affiliates. SELECT name, salary, salary - LAST_VALUE(salary) OVER w AS 'above', ROUND((salary - LAST_VALUE(salary) OVER w) / LAST_VALUE(salary) OVER w * 100) AS 'pct above' FROM staff WINDOW w as (ORDER by salary DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) ORDER BY salary DESC; +-------+---------+---------+-----------+ | name | salary | above | pct above | +-------+---------+---------+-----------+ | Mike | 7100.00 | 2500.00 | 54 | | Betty | 6300.00 | 1700.00 | 37 | | James | 6000.00 | 1400.00 | 30 | | Sandy | 5400.00 | 800.00 | 17 | | Andy | 5400.00 | 800.00 | 17 | | Tracy | 4800.00 | 200.00 | 4 | | Carol | 4600.00 | 0.00 | 0 |
  • 54. Calculate differences in salary Copyright © 2019 Oracle and/or its affiliates. SELECT name, dept, salary, round(AVG(salary) OVER z,2) AS 'Avg', round(salary - AVG(salary) OVER z,2) as 'diff avg' FROM staff WINDOW z AS (PARTITION BY dept) ORDER BY dept, salary DESC; +-------+-----------+---------+---------+----------+ | name | dept | salary | Avg | diff avg | +-------+-----------+---------+---------+----------+ | Mike | Marketing | 7100.00 | 6700.00 | 400.00 | | Betty | Marketing | 6300.00 | 6700.00 | -400.00 | | Sandy | Sales | 5400.00 | 5000.00 | 400.00 | | Carol | Sales | 4600.00 | 5000.00 | -400.00 | | James | Shipping | 6000.00 | 5400.00 | 600.00 | | Andy | Shipping | 5400.00 | 5400.00 | 0.00 | | Tracy | Shipping | 4800.00 | 5400.00 | -600.00 |
  • 55. Company and Departmental Ranks Copyright © 2019 Oracle and/or its affiliates. SELECT name, dept, salary, RANK() OVER s AS dept_rank, RANK() OVER (ORDER BY salary DESC) AS Company_rank FROM staff WINDOW s as (PARTITION BY dept ORDER BY salary DESC) ORDER BY dept, salary DESC; +-------+-----------+---------+-----------+--------------+ | name | dept | salary | dept_rank | Company_rank | +-------+-----------+---------+-----------+--------------+ | Mike | Marketing | 7100.00 | 1 | 1 | | Betty | Marketing | 6300.00 | 2 | 2 | | Sandy | Sales | 5400.00 | 1 | 4 | | Carol | Sales | 4600.00 | 2 | 7 | | James | Shipping | 6000.00 | 1 | 3 | | Andy | Shipping | 5400.00 | 2 | 4 | | Tracy | Shipping | 4800.00 | 3 | 6 |
  • 56. Good Place to Stop .. for now. Copyright © 2019 Oracle and/or its affiliates.
  • 57. Excellent Tutorial on Windowing Functions https://momjian.us/main/writings/pgsql/window.pdf Copyright © 2019 Oracle and/or its affiliates.
  • 59. Please buy my Book! Copyright © 2019 Oracle and/or its affiliates.
  • 60. Q/A Copyright © 2019 Oracle and/or its affiliates. Slides at Slideshare.net/davidmstokes Email at David.Stokes @ Oracle.com Blog at https://elephantdolphin.blogspot.com/