SlideShare a Scribd company logo
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
How to Find Patterns in Your Data with SQL
Chris Saxon, @ChrisRSaxon & @SQLDaily
blogs.oracle.com/sql
youtube.com/c/TheMagicofSQL
asktom.oracle.com
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Safe Harbor Statement
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, and timing of any features or
functionality described for Oracle’s products remains at the sole discretion of Oracle.
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
This presentation contains <regular expressions>!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon
I thought
this was
about SQL!
Ryan McGuire / Gratisography
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
* => zero or more matches
+ => one or more matches
{n,m} => N through M matches
(either optional)
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Am I Improving?
Can Beat My PB?
Am I Training Regularly?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Am I running
every day?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
#1
#3
#2
#4
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
How I know if rows are consecutive?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
current value = previous value + 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
lag ( run_date ) over
( order by run_date )
Get the previous row's date
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE RN TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 1 420 1
02 Jan 2018 2 2,400 5
03 Jan 2018 3 4,932 10
06 Jan 2018 4 2,350 5
07 Jan 2018 5 410 1
10 Jan 2018 6 400 1
13 Jan 2018 7 2,300 5
14 Jan 2018 8 425 1
15 Jan 2018 9 422 1
consecutive =>
constant gap
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE RN TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 1 420 1
02 Jan 2018 2 2,400 5
03 Jan 2018 3 4,932 10
06 Jan 2018 4 2,350 5
07 Jan 2018 5 410 1
10 Jan 2018 6 400 1
13 Jan 2018 7 2,300 5
14 Jan 2018 8 425 1
15 Jan 2018 9 422 1
-
-
-
-
-
-
-
-
-
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE RN RUN_DATE - RN TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 1 31 Dec 2017 420 1
02 Jan 2018 2 31 Dec 2017 2,400 5
03 Jan 2018 3 31 Dec 2017 4,932 10
06 Jan 2018 4 02 Jan 2018 2,350 5
07 Jan 2018 5 02 Jan 2018 410 1
10 Jan 2018 6 04 Jan 2018 400 1
13 Jan 2018 7 06 Jan 2018 2,300 5
14 Jan 2018 8 06 Jan 2018 425 1
15 Jan 2018 9 06 Jan 2018 422 1
-
-
-
-
-
-
-
-
-
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE RN RUN_DATE - RN TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 1 31 Dec 2017 420 1
02 Jan 2018 2 31 Dec 2017 2,400 5
03 Jan 2018 3 31 Dec 2017 4,932 10
06 Jan 2018 4 02 Jan 2018 2,350 5
07 Jan 2018 5 02 Jan 2018 410 1
10 Jan 2018 6 04 Jan 2018 400 1
13 Jan 2018 7 06 Jan 2018 2,300 5
14 Jan 2018 8 06 Jan 2018 425 1
15 Jan 2018 9 06 Jan 2018 422 1
-
-
-
-
-
-
-
-
-
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Tabibitosan Method
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
row_number ()
over ( order by run_date )
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
run_date -
row_number ()
over ( order by run_date ) grp
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
with grps as (
select run_date ,
run_date -
row_number ()
over ( order by run_date ) grp
from running_log r
)
select min ( run_date ), count (*)
from grps
group by grp
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
12c Pattern Matching
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
this = prev + 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
this = prev + 1
this = prev + 3
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
this = prev + 1
this = prev + 3
this ≠ prev + 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
define
consecutive as
run_date = prev ( run_date ) + 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( strt consecutive* )
define
consecutive as
run_date = prev ( run_date ) + 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( strt consecutive* )
define
consecutive as
run_date = prev ( run_date ) + 1
"Always true"
> 0 matches
Any row <>
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE VARIABLE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 STRT 420 1
02 Jan 2018 CONSECUTIVE 2,400 5
03 Jan 2018 CONSECUTIVE 4,932 10
06 Jan 2018 STRT 2,350 5
07 Jan 2018 CONSECUTIVE 410 1
10 Jan 2018 STRT 400 1
13 Jan 2018 STRT 2,300 5
14 Jan 2018 CONSECUTIVE 425 1
15 Jan 2018 CONSECUTIVE 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( strt consecutive* )
define
consecutive as
run_date = prev ( run_date ) + 1
Which row is prev?!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
order by run_date
pattern ( strt consecutive* )
define
consecutive as
run_date = prev ( run_date ) + 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as start_date,
count (*) as days
pattern ( strt consecutive* )
define
consecutive as
run_date = prev ( run_date ) + 1
);
How many consecutive rows?
From first row in group
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
START_DATE DAYS
01 Jan 2018 3
06 Jan 2018 2
10 Jan 2018 1
13 Jan 2018 3
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
So which is
better?
Pixabay
pattern
matching
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Performance ~ similar
Availability MR 12c vs 8i*
Readability personal pref
Match_recognize vs. Tabibitosan
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Am I running >= 3
times/week?
Pixabay
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
How I know if runs are in the same week?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
last Monday = prev last Monday
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
trunc ( run_date , 'iw' )
Return the start of the ISO week…
…Monday!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TRUNC(RUN_DATE, 'IW') TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 01 Jan 2018 420 1
02 Jan 2018 01 Jan 2018 2,400 5
03 Jan 2018 01 Jan 2018 4,932 10
06 Jan 2018 01 Jan 2018 2,350 5
07 Jan 2018 01 Jan 2018 410 1
10 Jan 2018 08 Jan 2018 400 1
13 Jan 2018 08 Jan 2018 2,300 5
14 Jan 2018 08 Jan 2018 425 1
15 Jan 2018 15 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
select trunc ( run_date , 'iw' ),
count(*)
from running_log
group by trunc ( run_date , 'iw' )
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
select trunc ( run_date , 'iw' ),
count(*)
from running_log
group by trunc ( run_date , 'iw' )
having count (*) >= 3
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
12c Pattern Matching
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
define
same_week as
trunc ( run_date, 'iw' ) =
prev ( trunc ( run_date, 'iw' ) )
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as start_date,
count (*) as days
pattern ( strt same_week* )
define
same_week as
trunc ( run_date, 'iw' ) =
prev ( trunc ( run_date, 'iw' ) )
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as start_date,
count (*) as days
pattern ( strt same_week {2, } )
define
same_week as
trunc ( run_date, 'iw' ) =
prev ( trunc ( run_date, 'iw' ) )
);
Two or more matches
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as start_date,
count (*) as days
pattern ( strt same_week {2, } )
define
same_week as
trunc ( run_date, 'iw' ) =
prev ( trunc ( run_date, 'iw' ) )
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as start_date,
count (*) as days
pattern ( strt consecutive* )
define
consecutive as
run_date = prev ( run_date ) + 1
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
How I can I find consecutive weeks
with >= 3 runs?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Find weeks >= 3 runs
then
check these are consecutive!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
with min_three_runs as (
select * from running_log
match_recognize (
order by run_date
measures
first ( trunc ( run_date, 'iw' ) )
as week_start,
count(*) as days
pattern ( strt same_week {2, } )
define
same_week as
trunc ( run_date, 'iw' ) =
prev ( trunc ( run_date, 'iw' ) )
)
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
How I can I find consecutive weeks?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
current Monday = prev Monday + 7
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Tabibitosan Method
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
WEEK_START RN WEEK_START – RN RUNS
01 Jan 2018 1 31 Dec 2017 5
08 Jan 2018 2 06 Jan 2018 3
15 Jan 2018 3 12 Jan 2018 4
05 Feb 2018 4 01 Feb 2018 3
12 Feb 2018 5 07 Feb 2018 3
05 Mar 2018 6 28 Feb 2018 3
12 Mar 2018 7 07 Mar 2018 4
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Tabibitosan Method
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
WEEK_START RN * 7 RUNS
01 Jan 2018 7 5
08 Jan 2018 14 3
15 Jan 2018 21 4
05 Feb 2018 28 3
12 Feb 2018 35 3
05 Mar 2018 42 3
12 Mar 2018 49 4
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
WEEK_START RN * 7 WEEK_START – ( RN * 7 ) RUNS
01 Jan 2018 7 25 Dec 2017 5
08 Jan 2018 14 25 Dec 2017 3
15 Jan 2018 21 25 Dec 2017 4
05 Feb 2018 28 08 Jan 2018 3
12 Feb 2018 35 08 Jan 2018 3
05 Mar 2018 42 22 Jan 2018 3
12 Mar 2018 49 22 Jan 2018 4
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
select run_date - ( 7 *
row_number()
over ( order by run_date )
) grp
from min_three_runs
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by week_start
measures
first ( week_start ) as start_date,
count (*) as weeks
pattern ( strt consecutive_weeks* )
define
consecutive_weeks as
week_start = prev ( week_start ) + 7
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Pixabay
Am I running >= 3
times in 7 days?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
current day < first day + 7
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
#1
#2
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 01 – 07 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 08 – 14 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 15 – 21 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 01 – 07 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 08 – 14 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 15 – 21 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 01 – 07 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 2,350 5
07 Jan 2018 410 1
10 Jan 2018 10 – 17 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
select r.*, min ( run_date ) over (
order by run_date
) mn_date
from running_log r
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE MN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 01 Jan 2018 420 1
02 Jan 2018 01 Jan 2018 2,400 5
03 Jan 2018 01 Jan 2018 4,932 10
06 Jan 2018 01 Jan 2018 2,350 5
07 Jan 2018 01 Jan 2018 410 1
10 Jan 2018 01 Jan 2018 400 1
13 Jan 2018 01 Jan 2018 2,300 5
14 Jan 2018 01 Jan 2018 425 1
15 Jan 2018 01 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Windowing clause to the rescue…
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
select r.*, min ( run_date ) over (
order by run_date
range between 7 preceding
and current row
) mn_date
from running_log r
Consider rows with values
in the previous 7 days
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE MN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 01 Jan 2018 420 1
02 Jan 2018 01 Jan 2018 2,400 5
03 Jan 2018 01 Jan 2018 4,932 10
06 Jan 2018 01 Jan 2018 2,350 5
07 Jan 2018 01 Jan 2018 410 1
10 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE MN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 01 Jan 2018 420 1
02 Jan 2018 01 Jan 2018 2,400 5
03 Jan 2018 01 Jan 2018 4,932 10
06 Jan 2018 01 Jan 2018 2,350 5
07 Jan 2018 01 Jan 2018 410 1
10 Jan 2018 03 Jan 2018 400 1
13 Jan 2018 2,300 5
14 Jan 2018 425 1
15 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE MN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 01 Jan 2018 420 1
02 Jan 2018 01 Jan 2018 2,400 5
03 Jan 2018 01 Jan 2018 4,932 10
06 Jan 2018 01 Jan 2018 2,350 5
07 Jan 2018 01 Jan 2018 410 1
10 Jan 2018 03 Jan 2018 400 1
13 Jan 2018 06 Jan 2018 2,300 5
14 Jan 2018 07 Jan 2018 425 1
15 Jan 2018 10 Jan 2018 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Windowing clause to the rescue!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
11.2 Recursive With
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
with rws as (
select r.*, row_number() over ( order by run_date ) rn
from running_log r
)
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
with rws as (
select r.*, row_number() over ( order by run_date ) rn
from running_log r
), within_7 (
run_date, time_in_s, distance_in_miles, rn, grp_start
) as (
select run_date, time_in_s, distance_in_miles, rn, run_date grp_start
from rws
where rn = 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
with rws as (
select r.*, row_number() over ( order by run_date ) rn
from running_log r
), within_7 (
run_date, time_in_s, distance_in_miles, rn, grp_start
) as (
select run_date, time_in_s, distance_in_miles, rn, run_date grp_start
from rws
where rn = 1
union all
select r.run_date, r.time_in_s, r.distance_in_miles, r.rn,
from within_7 w
join rws r
on w.rn + 1 = r.rn
)
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
with rws as (
select r.*, row_number() over ( order by run_date ) rn
from running_log r
), within_7 (
run_date, time_in_s, distance_in_miles, rn, grp_start
) as (
select run_date, time_in_s, distance_in_miles, rn, run_date grp_start
from rws
where rn = 1
union all
select r.run_date, r.time_in_s, r.distance_in_miles, r.rn,
case
when r.run_date < w.grp_start + 7 then grp_start
else r.run_date
end grp_start
from within_7 w
join rws r
on w.rn + 1 = r.rn
)
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
with rws as (
select r.*, row_number() over ( order by run_date ) rn
from running_log r
), within_7 (
run_date, time_in_s, distance_in_miles, rn, grp_start
) as (
select run_date, time_in_s, distance_in_miles, rn, run_date grp_start
from rws
where rn = 1
union all
select r.run_date, r.time_in_s, r.distance_in_miles, r.rn,
case
when r.run_date < w.grp_start + 7 then grp_start
else r.run_date
end grp_start
from within_7 w
join rws r
on w.rn + 1 = r.rn
)
select grp, w.*
from within_7 w
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
10g Model
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
select * from running_log
model
dimension by ( row_number() over ( order by run_date ) rn )
measures ( run_date, 1 grp, run_date grp_start )
rules (
grp_start[1] = run_date[cv()],
grp_start[any] =
case
when run_date[cv()] < grp_start[cv()-1] + 7 then
grp_start[cv() - 1]
else run_date[cv()]
end ,
grp[any] =
case
when run_date[cv()] < grp_start[cv()-1] + 7 then
grp[cv() - 1]
else nvl(grp[cv() - 1] + 1, 1)
end
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
12c Pattern Matching
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
current day < first day + 7
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
define
within7 as
run_date < first ( run_date ) + 7
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( within7+ )
define
within7 as
run_date < first ( run_date ) + 7
> 1 matches
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as start_date,
count (*) as days
pattern ( within7+ )
define
within7 as
run_date < first ( run_date ) + 7
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Am I getting
faster? stocksnap.io
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
current time < prev time
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Analytic Functions
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
lag ( time_in_s )
over ( order by run_date )
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
select r.*, case
when time_in_s <
lag ( time_in_s )
over ( order by run_date )
then 'FASTER'
else 'SLOWER'
end faster
from running_log r
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
12c Pattern Matching
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
current time < prev time
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
define
faster as
time_in_s < prev ( time_in_s )
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( slower faster* )
define
faster as
time_in_s < prev ( time_in_s )
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
classifier () as faster
pattern ( slower faster* )
define
faster as
time_in_s < prev ( time_in_s )
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
FASTER
SLOWER
SLOWER
FASTER
FASTER
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
classifier () as faster
one row per match
pattern ( slower faster* )
define
faster as
time_in_s < prev ( time_in_s )
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
classifier () as faster
all rows per match
pattern ( slower faster* )
define
faster as
time_in_s < prev ( time_in_s )
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE FASTER TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 SLOWER 420 1
02 Jan 2018 SLOWER 2,400 5
03 Jan 2018 SLOWER 4,932 10
06 Jan 2018 FASTER 2,350 5
07 Jan 2018 FASTER 410 1
10 Jan 2018 FASTER 400 1
13 Jan 2018 SLOWER 2,300 5
14 Jan 2018 FASTER 425 1
15 Jan 2018 FASTER 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE FASTER TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 SLOWER 420 1
02 Jan 2018 SLOWER 2,400 5
03 Jan 2018 SLOWER 4,932 10
06 Jan 2018 FASTER 2,350 5
07 Jan 2018 FASTER 410 1
10 Jan 2018 FASTER 400 1
13 Jan 2018 SLOWER 2,300 5
14 Jan 2018 FASTER 425 1
15 Jan 2018 FASTER 422 1
SLOWER!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
07 Jan 2018 410 1
10 Jan 2018 400 1
14 Jan 2018 425 1
15 Jan 2018 422 1
02 Jan 2018 2,400 5
06 Jan 2018 2,350 5
13 Jan 2018 2,300 5
03 Jan 2018 4,932 10
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
partition by distance_in_miles
order by run_date
measures
classifier () as faster
all rows per match
pattern ( slower faster* )
define
faster as
time_in_s < prev ( time_in_s )
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE FASTER TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 SLOWER 420 1
07 Jan 2018 FASTER 410 1
10 Jan 2018 FASTER 400 1
14 Jan 2018 SLOWER 425 1
15 Jan 2018 FASTER 422 1
02 Jan 2018 SLOWER 2,400 5
06 Jan 2018 FASTER 2,350 5
13 Jan 2018 FASTER 2,300 5
03 Jan 2018 SLOWER 4,932 10
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Can I run 10k in
< 50 minutes?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Sum the total distance for runs
with a total time < 50 minutes
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
cumulative time <= 3,000 seconds
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( fifty_minutes+ )
define
fifty_minutes as
sum ( time_in_s ) <= 3000
Returns the running total
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as strt ,
sum ( time_in_s ) as total_time,
sum ( distance_in_miles ) as dist
pattern ( fifty_minutes+ )
define
fifty_minutes as
sum ( time_in_s ) <= 3000
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
STRT TOTAL_TIME DIST
01 Jan 2018 2,820 6
06 Jan 2018 2,760 6
10 Jan 2018 2,700 6
14 Jan 2018 847 2
Where's my 10 mile run?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
any runs cumulative time < 3,000
and
one run cumulative time >= 3,000
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( )
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( under_fifty* over_fifty )
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( under_fifty* over_fifty )
define
under_fifty as
sum ( time_in_s ) < 3000,
over_fifty as
sum ( time_in_s ) >= 3000
);
Includes under_fifty values
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as strt ,
sum ( time_in_s ) as total_time,
sum ( distance_in_miles ) as dist
pattern ( under_fifty* over_fifty )
define
under_fifty as
sum ( time_in_s ) < 3000,
over_fifty as
sum ( time_in_s ) >= 3000
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
STRT TOTAL_TIME DIST
01 Jan 2018 7,752 16
06 Jan 2018 3,160 7
13 Jan 2018 3,147 7
Hmmm….
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as strt ,
sum ( time_in_s ) as total_time,
sum ( distance_in_miles ) as dist
after match skip past last row
pattern ( under_fifty* over_fifty )
define
under_fifty as
sum ( time_in_s ) < 3000,
over_fifty as
sum ( time_in_s ) >= 3000
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as strt ,
sum ( time_in_s ) as total_time,
sum ( distance_in_miles ) as dist
after match skip to next row
pattern ( under_fifty* over_fifty )
define
under_fifty as
sum ( time_in_s ) < 3000,
over_fifty as
sum ( time_in_s ) >= 3000
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
STRT TOTAL_TIME DIST
01 Jan 2018 7,752 16
02 Jan 2018 7,332 15
03 Jan 2018 4,932 10
06 Jan 2018 3,160 7
07 Jan 2018 3,110 7
10 Jan 2018 3,125 7
13 Jan 2018 3,147 7
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Pixabay
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
How often did I run 5 miles
Followed by 2+ 1 mile runs
Within 7 days?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( five_mile one_mile {2,} )
define
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( five_mile one_mile {2,} )
define
five_mile as distance_in_miles = 5,
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( five_mile one_mile {2,} )
define
five_mile as distance_in_miles = 5,
one_mile as distance_in_miles = 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
pattern ( five_mile one_mile {2,} )
define
five_mile as distance_in_miles = 5,
one_mile as distance_in_miles = 1
and run_date < first ( run_date ) + 7
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
first ( run_date ) as start_date,
count (*) as total_runs
pattern ( five_mile one_mile {2,} )
define
five_mile as distance_in_miles = 5,
one_mile as distance_in_miles = 1
and run_date < first ( run_date ) + 7
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
STRT TOTAL_RUNS
06 Jan 2018 3
13 Jan 2018 3
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Why would I want to do that?!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Pixabay
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
How do
I debug it?
Gratisography
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
(Regular) [exprsion]+ are easy to missteak
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
regex101.comregex101.com
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
classifier
=> Which variable matched?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
classifier
=> Which variable matched?
match_number
=> Which group is this?
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
classifier
=> Which variable matched?
match_number
=> Which group is this?
all rows per match
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
classifier
=> Which variable matched?
match_number
=> Which group is this?
all rows per match with unmatched rows
=> Show me everything!
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
match_recognize (
order by run_date
measures
classifier () as var,
match_number () as grp
all rows per match with unmatched rows
pattern ( five_mile one_mile {2,} )
define
five_mile as distance_in_miles = 5,
one_mile as distance_in_miles = 1
and run_date < first ( run_date ) + 7
);
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
RUN_DATE VAR GRP TIME_IN_S DISTANCE_IN_MILES
01 Jan 2018 420 1
02 Jan 2018 2,400 5
03 Jan 2018 4,932 10
06 Jan 2018 FIVE_MILE 1 2,350 5
07 Jan 2018 ONE_MILE 1 410 1
10 Jan 2018 ONE_MILE 1 400 1
13 Jan 2018 FIVE_MILE 2 2,300 5
14 Jan 2018 ONE_MILE 2 425 1
15 Jan 2018 ONE_MILE 2 422 1
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Want more?
Pixabay
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
iTunes & PDF
FREE!
SQL for Data Warehousing and Analytics
https://oracle-big-data.blogspot.co.uk
Keith Laker
Analytic SQL PM
Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Gratisography
#MakeDataGreatAgain
oracle-big-data.blogspot.co.uk

More Related Content

PPTX
Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 1
PDF
Oracle Real Application Clusters (RAC) 12c Rel. 2 - Operational Best Practices
PDF
Securefile LOBs
PPT
Your tuning arsenal: AWR, ADDM, ASH, Metrics and Advisors
PDF
Row Pattern Matching in SQL:2016
PPTX
Extreme Replication - Performance Tuning Oracle GoldenGate
PDF
Oracle Advanced SQL and Analytic Functions
PDF
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...
Stop the Chaos! Get Real Oracle Performance by Query Tuning Part 1
Oracle Real Application Clusters (RAC) 12c Rel. 2 - Operational Best Practices
Securefile LOBs
Your tuning arsenal: AWR, ADDM, ASH, Metrics and Advisors
Row Pattern Matching in SQL:2016
Extreme Replication - Performance Tuning Oracle GoldenGate
Oracle Advanced SQL and Analytic Functions
Exploring Oracle Database Performance Tuning Best Practices for DBAs and Deve...

What's hot (20)

PDF
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
PDF
Analyzing and Interpreting AWR
PDF
Chasing the optimizer
PDF
EBS-technical_upgrade_best_practices 12.1 or 12.2
PPTX
ORACLE PL SQL FOR BEGINNERS
PPTX
Enable GoldenGate Monitoring with OEM 12c/JAgent
PDF
Redis cluster
PPTX
Oracle sql high performance tuning
PDF
Oracle Performance Tuning Fundamentals
PPTX
AWR and ASH Deep Dive
PDF
Oracle LOB Internals and Performance Tuning
PPT
SQL subquery
PDF
Troubleshooting Complex Performance issues - Oracle SEG$ contention
PPTX
Sql Basics And Advanced
PDF
Oracle statistics by example
PDF
Tanel Poder - Performance stories from Exadata Migrations
PDF
SQL Monitoring in Oracle Database 12c
PDF
[APJ] Common Table Expressions (CTEs) in SQL
 
PPT
Cursores.ppt
DOC
AWR reports-Measuring CPU
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
Analyzing and Interpreting AWR
Chasing the optimizer
EBS-technical_upgrade_best_practices 12.1 or 12.2
ORACLE PL SQL FOR BEGINNERS
Enable GoldenGate Monitoring with OEM 12c/JAgent
Redis cluster
Oracle sql high performance tuning
Oracle Performance Tuning Fundamentals
AWR and ASH Deep Dive
Oracle LOB Internals and Performance Tuning
SQL subquery
Troubleshooting Complex Performance issues - Oracle SEG$ contention
Sql Basics And Advanced
Oracle statistics by example
Tanel Poder - Performance stories from Exadata Migrations
SQL Monitoring in Oracle Database 12c
[APJ] Common Table Expressions (CTEs) in SQL
 
Cursores.ppt
AWR reports-Measuring CPU
Ad

Similar to How to Find Patterns in Your Data with SQL (20)

PDF
What Is SAS | SAS Tutorial For Beginners | SAS Training | SAS Programming | E...
PDF
PGQL: A Language for Graphs
PDF
20190615 hkos-mysql-troubleshootingandperformancev2
PDF
2018 JCP Year End Summary
PDF
Azure HDlnsight에서 R 및 Spark를 이용하여 확장 가능한 머신러닝
PDF
ReactJS Tutorial For Beginners | ReactJS Redux Training For Beginners | React...
PPTX
#dbhouseparty - Real World Problem Solving with SQL
PDF
2019 JCP Program Year End Summary
PDF
Top 10 SQL Performance tips & tricks for Java Developers
PPTX
Melbourne Groundbreakers Tour - Upgrading without risk
PPTX
Sangam 18 - The New Optimizer in Oracle 12c
PDF
Streaming solutions for real time problems
PDF
Rootconf admin101
PDF
R Tutorial For Beginners | R Programming Tutorial l R Language For Beginners ...
PDF
Python and the MySQL Document Store
PDF
How To Become A Big Data Engineer? Edureka
PDF
12 Things Developers Will Love About Oracle Database 12c Release 2
PDF
Building Applications with Apache MXNet
PDF
React Redux Tutorial | Redux Tutorial for Beginners | React Redux Training | ...
PDF
Customer-Product Analysis With Tableau | Tableau Training For Beginners | Tab...
What Is SAS | SAS Tutorial For Beginners | SAS Training | SAS Programming | E...
PGQL: A Language for Graphs
20190615 hkos-mysql-troubleshootingandperformancev2
2018 JCP Year End Summary
Azure HDlnsight에서 R 및 Spark를 이용하여 확장 가능한 머신러닝
ReactJS Tutorial For Beginners | ReactJS Redux Training For Beginners | React...
#dbhouseparty - Real World Problem Solving with SQL
2019 JCP Program Year End Summary
Top 10 SQL Performance tips & tricks for Java Developers
Melbourne Groundbreakers Tour - Upgrading without risk
Sangam 18 - The New Optimizer in Oracle 12c
Streaming solutions for real time problems
Rootconf admin101
R Tutorial For Beginners | R Programming Tutorial l R Language For Beginners ...
Python and the MySQL Document Store
How To Become A Big Data Engineer? Edureka
12 Things Developers Will Love About Oracle Database 12c Release 2
Building Applications with Apache MXNet
React Redux Tutorial | Redux Tutorial for Beginners | React Redux Training | ...
Customer-Product Analysis With Tableau | Tableau Training For Beginners | Tab...
Ad

More from Chris Saxon (7)

PDF
Game of Fraud Detection with SQL and Machine Learning
PDF
Agile Database Development with JSON
PDF
Polymorphic Table Functions in SQL
PDF
Using Edition-Based Redefinition for Zero Downtime PL/SQL Changes
PDF
Why Isn't My Query Using an Index? An Introduction to SQL Performance
PDF
How to Hack Your App Using SQL Injection
PDF
18(ish) Things You'll Love About Oracle Database 18c
Game of Fraud Detection with SQL and Machine Learning
Agile Database Development with JSON
Polymorphic Table Functions in SQL
Using Edition-Based Redefinition for Zero Downtime PL/SQL Changes
Why Isn't My Query Using an Index? An Introduction to SQL Performance
How to Hack Your App Using SQL Injection
18(ish) Things You'll Love About Oracle Database 18c

Recently uploaded (20)

PDF
BF and FI - Blockchain, fintech and Financial Innovation Lesson 2.pdf
PDF
Introduction to Data Science and Data Analysis
PPTX
iec ppt-1 pptx icmr ppt on rehabilitation.pptx
PDF
Lecture1 pattern recognition............
PPTX
climate analysis of Dhaka ,Banglades.pptx
PPTX
STERILIZATION AND DISINFECTION-1.ppthhhbx
PDF
Recruitment and Placement PPT.pdfbjfibjdfbjfobj
PPTX
SAP 2 completion done . PRESENTATION.pptx
PPTX
Computer network topology notes for revision
PDF
Fluorescence-microscope_Botany_detailed content
PPTX
Introduction to Knowledge Engineering Part 1
PPTX
IB Computer Science - Internal Assessment.pptx
PPT
Reliability_Chapter_ presentation 1221.5784
PDF
[EN] Industrial Machine Downtime Prediction
PPTX
Market Analysis -202507- Wind-Solar+Hybrid+Street+Lights+for+the+North+Amer...
PPTX
Introduction to Firewall Analytics - Interfirewall and Transfirewall.pptx
PDF
Galatica Smart Energy Infrastructure Startup Pitch Deck
PPTX
STUDY DESIGN details- Lt Col Maksud (21).pptx
PPTX
ALIMENTARY AND BILIARY CONDITIONS 3-1.pptx
PPTX
Data_Analytics_and_PowerBI_Presentation.pptx
BF and FI - Blockchain, fintech and Financial Innovation Lesson 2.pdf
Introduction to Data Science and Data Analysis
iec ppt-1 pptx icmr ppt on rehabilitation.pptx
Lecture1 pattern recognition............
climate analysis of Dhaka ,Banglades.pptx
STERILIZATION AND DISINFECTION-1.ppthhhbx
Recruitment and Placement PPT.pdfbjfibjdfbjfobj
SAP 2 completion done . PRESENTATION.pptx
Computer network topology notes for revision
Fluorescence-microscope_Botany_detailed content
Introduction to Knowledge Engineering Part 1
IB Computer Science - Internal Assessment.pptx
Reliability_Chapter_ presentation 1221.5784
[EN] Industrial Machine Downtime Prediction
Market Analysis -202507- Wind-Solar+Hybrid+Street+Lights+for+the+North+Amer...
Introduction to Firewall Analytics - Interfirewall and Transfirewall.pptx
Galatica Smart Energy Infrastructure Startup Pitch Deck
STUDY DESIGN details- Lt Col Maksud (21).pptx
ALIMENTARY AND BILIARY CONDITIONS 3-1.pptx
Data_Analytics_and_PowerBI_Presentation.pptx

How to Find Patterns in Your Data with SQL

  • 1. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | How to Find Patterns in Your Data with SQL Chris Saxon, @ChrisRSaxon & @SQLDaily blogs.oracle.com/sql youtube.com/c/TheMagicofSQL asktom.oracle.com
  • 2. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Safe Harbor Statement 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, and timing of any features or functionality described for Oracle’s products remains at the sole discretion of Oracle.
  • 3. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | This presentation contains <regular expressions>!
  • 4. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | blogs.oracle.com/sql www.youtube.com/c/TheMagicOfSQL @ChrisRSaxon I thought this was about SQL! Ryan McGuire / Gratisography
  • 5. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
  • 6. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | * => zero or more matches + => one or more matches {n,m} => N through M matches (either optional)
  • 7. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Am I Improving? Can Beat My PB? Am I Training Regularly?
  • 8. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Am I running every day?
  • 9. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1
  • 10. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1 #1 #3 #2 #4
  • 11. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | How I know if rows are consecutive?
  • 12. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | current value = previous value + 1
  • 13. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | lag ( run_date ) over ( order by run_date ) Get the previous row's date
  • 14. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE RN TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 1 420 1 02 Jan 2018 2 2,400 5 03 Jan 2018 3 4,932 10 06 Jan 2018 4 2,350 5 07 Jan 2018 5 410 1 10 Jan 2018 6 400 1 13 Jan 2018 7 2,300 5 14 Jan 2018 8 425 1 15 Jan 2018 9 422 1 consecutive => constant gap
  • 15. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE RN TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 1 420 1 02 Jan 2018 2 2,400 5 03 Jan 2018 3 4,932 10 06 Jan 2018 4 2,350 5 07 Jan 2018 5 410 1 10 Jan 2018 6 400 1 13 Jan 2018 7 2,300 5 14 Jan 2018 8 425 1 15 Jan 2018 9 422 1 - - - - - - - - -
  • 16. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE RN RUN_DATE - RN TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 1 31 Dec 2017 420 1 02 Jan 2018 2 31 Dec 2017 2,400 5 03 Jan 2018 3 31 Dec 2017 4,932 10 06 Jan 2018 4 02 Jan 2018 2,350 5 07 Jan 2018 5 02 Jan 2018 410 1 10 Jan 2018 6 04 Jan 2018 400 1 13 Jan 2018 7 06 Jan 2018 2,300 5 14 Jan 2018 8 06 Jan 2018 425 1 15 Jan 2018 9 06 Jan 2018 422 1 - - - - - - - - -
  • 17. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE RN RUN_DATE - RN TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 1 31 Dec 2017 420 1 02 Jan 2018 2 31 Dec 2017 2,400 5 03 Jan 2018 3 31 Dec 2017 4,932 10 06 Jan 2018 4 02 Jan 2018 2,350 5 07 Jan 2018 5 02 Jan 2018 410 1 10 Jan 2018 6 04 Jan 2018 400 1 13 Jan 2018 7 06 Jan 2018 2,300 5 14 Jan 2018 8 06 Jan 2018 425 1 15 Jan 2018 9 06 Jan 2018 422 1 - - - - - - - - -
  • 18. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Tabibitosan Method
  • 19. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | row_number () over ( order by run_date )
  • 20. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | run_date - row_number () over ( order by run_date ) grp
  • 21. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | with grps as ( select run_date , run_date - row_number () over ( order by run_date ) grp from running_log r ) select min ( run_date ), count (*) from grps group by grp
  • 22. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | 12c Pattern Matching
  • 23. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1 this = prev + 1
  • 24. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1 this = prev + 1 this = prev + 3
  • 25. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1 this = prev + 1 this = prev + 3 this ≠ prev + 1
  • 26. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | define consecutive as run_date = prev ( run_date ) + 1
  • 27. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( strt consecutive* ) define consecutive as run_date = prev ( run_date ) + 1
  • 28. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( strt consecutive* ) define consecutive as run_date = prev ( run_date ) + 1 "Always true" > 0 matches Any row <>
  • 29. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE VARIABLE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 STRT 420 1 02 Jan 2018 CONSECUTIVE 2,400 5 03 Jan 2018 CONSECUTIVE 4,932 10 06 Jan 2018 STRT 2,350 5 07 Jan 2018 CONSECUTIVE 410 1 10 Jan 2018 STRT 400 1 13 Jan 2018 STRT 2,300 5 14 Jan 2018 CONSECUTIVE 425 1 15 Jan 2018 CONSECUTIVE 422 1
  • 30. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( strt consecutive* ) define consecutive as run_date = prev ( run_date ) + 1 Which row is prev?!
  • 31. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | order by run_date pattern ( strt consecutive* ) define consecutive as run_date = prev ( run_date ) + 1
  • 32. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as start_date, count (*) as days pattern ( strt consecutive* ) define consecutive as run_date = prev ( run_date ) + 1 ); How many consecutive rows? From first row in group
  • 33. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | START_DATE DAYS 01 Jan 2018 3 06 Jan 2018 2 10 Jan 2018 1 13 Jan 2018 3
  • 34. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | So which is better? Pixabay pattern matching
  • 35. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Performance ~ similar Availability MR 12c vs 8i* Readability personal pref Match_recognize vs. Tabibitosan
  • 36. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Am I running >= 3 times/week? Pixabay
  • 37. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | How I know if runs are in the same week?
  • 38. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | last Monday = prev last Monday
  • 39. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | trunc ( run_date , 'iw' ) Return the start of the ISO week… …Monday!
  • 40. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TRUNC(RUN_DATE, 'IW') TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 01 Jan 2018 420 1 02 Jan 2018 01 Jan 2018 2,400 5 03 Jan 2018 01 Jan 2018 4,932 10 06 Jan 2018 01 Jan 2018 2,350 5 07 Jan 2018 01 Jan 2018 410 1 10 Jan 2018 08 Jan 2018 400 1 13 Jan 2018 08 Jan 2018 2,300 5 14 Jan 2018 08 Jan 2018 425 1 15 Jan 2018 15 Jan 2018 422 1
  • 41. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | select trunc ( run_date , 'iw' ), count(*) from running_log group by trunc ( run_date , 'iw' )
  • 42. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | select trunc ( run_date , 'iw' ), count(*) from running_log group by trunc ( run_date , 'iw' ) having count (*) >= 3
  • 43. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | 12c Pattern Matching
  • 44. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | define same_week as trunc ( run_date, 'iw' ) = prev ( trunc ( run_date, 'iw' ) )
  • 45. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as start_date, count (*) as days pattern ( strt same_week* ) define same_week as trunc ( run_date, 'iw' ) = prev ( trunc ( run_date, 'iw' ) ) );
  • 46. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as start_date, count (*) as days pattern ( strt same_week {2, } ) define same_week as trunc ( run_date, 'iw' ) = prev ( trunc ( run_date, 'iw' ) ) ); Two or more matches
  • 47. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as start_date, count (*) as days pattern ( strt same_week {2, } ) define same_week as trunc ( run_date, 'iw' ) = prev ( trunc ( run_date, 'iw' ) ) );
  • 48. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as start_date, count (*) as days pattern ( strt consecutive* ) define consecutive as run_date = prev ( run_date ) + 1 );
  • 49. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | How I can I find consecutive weeks with >= 3 runs?
  • 50. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Find weeks >= 3 runs then check these are consecutive!
  • 51. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | with min_three_runs as ( select * from running_log match_recognize ( order by run_date measures first ( trunc ( run_date, 'iw' ) ) as week_start, count(*) as days pattern ( strt same_week {2, } ) define same_week as trunc ( run_date, 'iw' ) = prev ( trunc ( run_date, 'iw' ) ) )
  • 52. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | How I can I find consecutive weeks?
  • 53. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | current Monday = prev Monday + 7
  • 54. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Tabibitosan Method
  • 55. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | WEEK_START RN WEEK_START – RN RUNS 01 Jan 2018 1 31 Dec 2017 5 08 Jan 2018 2 06 Jan 2018 3 15 Jan 2018 3 12 Jan 2018 4 05 Feb 2018 4 01 Feb 2018 3 12 Feb 2018 5 07 Feb 2018 3 05 Mar 2018 6 28 Feb 2018 3 12 Mar 2018 7 07 Mar 2018 4
  • 56. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Tabibitosan Method
  • 57. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | WEEK_START RN * 7 RUNS 01 Jan 2018 7 5 08 Jan 2018 14 3 15 Jan 2018 21 4 05 Feb 2018 28 3 12 Feb 2018 35 3 05 Mar 2018 42 3 12 Mar 2018 49 4
  • 58. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | WEEK_START RN * 7 WEEK_START – ( RN * 7 ) RUNS 01 Jan 2018 7 25 Dec 2017 5 08 Jan 2018 14 25 Dec 2017 3 15 Jan 2018 21 25 Dec 2017 4 05 Feb 2018 28 08 Jan 2018 3 12 Feb 2018 35 08 Jan 2018 3 05 Mar 2018 42 22 Jan 2018 3 12 Mar 2018 49 22 Jan 2018 4
  • 59. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | select run_date - ( 7 * row_number() over ( order by run_date ) ) grp from min_three_runs
  • 60. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by week_start measures first ( week_start ) as start_date, count (*) as weeks pattern ( strt consecutive_weeks* ) define consecutive_weeks as week_start = prev ( week_start ) + 7 );
  • 61. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
  • 62. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Pixabay Am I running >= 3 times in 7 days?
  • 63. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | current day < first day + 7
  • 64. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1
  • 65. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1 #1 #2
  • 66. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 01 – 07 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 08 – 14 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 15 – 21 Jan 2018 422 1
  • 67. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 01 – 07 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 08 – 14 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 15 – 21 Jan 2018 422 1
  • 68. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 01 – 07 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 2,350 5 07 Jan 2018 410 1 10 Jan 2018 10 – 17 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1
  • 69. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | select r.*, min ( run_date ) over ( order by run_date ) mn_date from running_log r
  • 70. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE MN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 01 Jan 2018 420 1 02 Jan 2018 01 Jan 2018 2,400 5 03 Jan 2018 01 Jan 2018 4,932 10 06 Jan 2018 01 Jan 2018 2,350 5 07 Jan 2018 01 Jan 2018 410 1 10 Jan 2018 01 Jan 2018 400 1 13 Jan 2018 01 Jan 2018 2,300 5 14 Jan 2018 01 Jan 2018 425 1 15 Jan 2018 01 Jan 2018 422 1
  • 71. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Windowing clause to the rescue…
  • 72. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | select r.*, min ( run_date ) over ( order by run_date range between 7 preceding and current row ) mn_date from running_log r Consider rows with values in the previous 7 days
  • 73. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE MN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 01 Jan 2018 420 1 02 Jan 2018 01 Jan 2018 2,400 5 03 Jan 2018 01 Jan 2018 4,932 10 06 Jan 2018 01 Jan 2018 2,350 5 07 Jan 2018 01 Jan 2018 410 1 10 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1
  • 74. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE MN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 01 Jan 2018 420 1 02 Jan 2018 01 Jan 2018 2,400 5 03 Jan 2018 01 Jan 2018 4,932 10 06 Jan 2018 01 Jan 2018 2,350 5 07 Jan 2018 01 Jan 2018 410 1 10 Jan 2018 03 Jan 2018 400 1 13 Jan 2018 2,300 5 14 Jan 2018 425 1 15 Jan 2018 422 1
  • 75. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE MN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 01 Jan 2018 420 1 02 Jan 2018 01 Jan 2018 2,400 5 03 Jan 2018 01 Jan 2018 4,932 10 06 Jan 2018 01 Jan 2018 2,350 5 07 Jan 2018 01 Jan 2018 410 1 10 Jan 2018 03 Jan 2018 400 1 13 Jan 2018 06 Jan 2018 2,300 5 14 Jan 2018 07 Jan 2018 425 1 15 Jan 2018 10 Jan 2018 422 1
  • 76. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Windowing clause to the rescue!
  • 77. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | 11.2 Recursive With
  • 78. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | with rws as ( select r.*, row_number() over ( order by run_date ) rn from running_log r )
  • 79. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | with rws as ( select r.*, row_number() over ( order by run_date ) rn from running_log r ), within_7 ( run_date, time_in_s, distance_in_miles, rn, grp_start ) as ( select run_date, time_in_s, distance_in_miles, rn, run_date grp_start from rws where rn = 1
  • 80. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | with rws as ( select r.*, row_number() over ( order by run_date ) rn from running_log r ), within_7 ( run_date, time_in_s, distance_in_miles, rn, grp_start ) as ( select run_date, time_in_s, distance_in_miles, rn, run_date grp_start from rws where rn = 1 union all select r.run_date, r.time_in_s, r.distance_in_miles, r.rn, from within_7 w join rws r on w.rn + 1 = r.rn )
  • 81. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | with rws as ( select r.*, row_number() over ( order by run_date ) rn from running_log r ), within_7 ( run_date, time_in_s, distance_in_miles, rn, grp_start ) as ( select run_date, time_in_s, distance_in_miles, rn, run_date grp_start from rws where rn = 1 union all select r.run_date, r.time_in_s, r.distance_in_miles, r.rn, case when r.run_date < w.grp_start + 7 then grp_start else r.run_date end grp_start from within_7 w join rws r on w.rn + 1 = r.rn )
  • 82. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | with rws as ( select r.*, row_number() over ( order by run_date ) rn from running_log r ), within_7 ( run_date, time_in_s, distance_in_miles, rn, grp_start ) as ( select run_date, time_in_s, distance_in_miles, rn, run_date grp_start from rws where rn = 1 union all select r.run_date, r.time_in_s, r.distance_in_miles, r.rn, case when r.run_date < w.grp_start + 7 then grp_start else r.run_date end grp_start from within_7 w join rws r on w.rn + 1 = r.rn ) select grp, w.* from within_7 w
  • 83. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | 10g Model
  • 84. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | select * from running_log model dimension by ( row_number() over ( order by run_date ) rn ) measures ( run_date, 1 grp, run_date grp_start ) rules ( grp_start[1] = run_date[cv()], grp_start[any] = case when run_date[cv()] < grp_start[cv()-1] + 7 then grp_start[cv() - 1] else run_date[cv()] end , grp[any] = case when run_date[cv()] < grp_start[cv()-1] + 7 then grp[cv() - 1] else nvl(grp[cv() - 1] + 1, 1) end );
  • 85. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | 12c Pattern Matching
  • 86. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | current day < first day + 7
  • 87. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | define within7 as run_date < first ( run_date ) + 7
  • 88. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( within7+ ) define within7 as run_date < first ( run_date ) + 7 > 1 matches
  • 89. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as start_date, count (*) as days pattern ( within7+ ) define within7 as run_date < first ( run_date ) + 7 );
  • 90. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Am I getting faster? stocksnap.io
  • 91. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | current time < prev time
  • 92. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Analytic Functions
  • 93. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | lag ( time_in_s ) over ( order by run_date )
  • 94. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | select r.*, case when time_in_s < lag ( time_in_s ) over ( order by run_date ) then 'FASTER' else 'SLOWER' end faster from running_log r
  • 95. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | 12c Pattern Matching
  • 96. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | current time < prev time
  • 97. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | define faster as time_in_s < prev ( time_in_s )
  • 98. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( slower faster* ) define faster as time_in_s < prev ( time_in_s )
  • 99. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures classifier () as faster pattern ( slower faster* ) define faster as time_in_s < prev ( time_in_s ) );
  • 100. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | FASTER SLOWER SLOWER FASTER FASTER
  • 101. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures classifier () as faster one row per match pattern ( slower faster* ) define faster as time_in_s < prev ( time_in_s ) );
  • 102. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures classifier () as faster all rows per match pattern ( slower faster* ) define faster as time_in_s < prev ( time_in_s ) );
  • 103. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE FASTER TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 SLOWER 420 1 02 Jan 2018 SLOWER 2,400 5 03 Jan 2018 SLOWER 4,932 10 06 Jan 2018 FASTER 2,350 5 07 Jan 2018 FASTER 410 1 10 Jan 2018 FASTER 400 1 13 Jan 2018 SLOWER 2,300 5 14 Jan 2018 FASTER 425 1 15 Jan 2018 FASTER 422 1
  • 104. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE FASTER TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 SLOWER 420 1 02 Jan 2018 SLOWER 2,400 5 03 Jan 2018 SLOWER 4,932 10 06 Jan 2018 FASTER 2,350 5 07 Jan 2018 FASTER 410 1 10 Jan 2018 FASTER 400 1 13 Jan 2018 SLOWER 2,300 5 14 Jan 2018 FASTER 425 1 15 Jan 2018 FASTER 422 1 SLOWER!
  • 105. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 07 Jan 2018 410 1 10 Jan 2018 400 1 14 Jan 2018 425 1 15 Jan 2018 422 1 02 Jan 2018 2,400 5 06 Jan 2018 2,350 5 13 Jan 2018 2,300 5 03 Jan 2018 4,932 10
  • 106. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( partition by distance_in_miles order by run_date measures classifier () as faster all rows per match pattern ( slower faster* ) define faster as time_in_s < prev ( time_in_s ) );
  • 107. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE FASTER TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 SLOWER 420 1 07 Jan 2018 FASTER 410 1 10 Jan 2018 FASTER 400 1 14 Jan 2018 SLOWER 425 1 15 Jan 2018 FASTER 422 1 02 Jan 2018 SLOWER 2,400 5 06 Jan 2018 FASTER 2,350 5 13 Jan 2018 FASTER 2,300 5 03 Jan 2018 SLOWER 4,932 10
  • 108. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Can I run 10k in < 50 minutes?
  • 109. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Sum the total distance for runs with a total time < 50 minutes
  • 110. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | cumulative time <= 3,000 seconds
  • 111. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( fifty_minutes+ ) define fifty_minutes as sum ( time_in_s ) <= 3000 Returns the running total
  • 112. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as strt , sum ( time_in_s ) as total_time, sum ( distance_in_miles ) as dist pattern ( fifty_minutes+ ) define fifty_minutes as sum ( time_in_s ) <= 3000 );
  • 113. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | STRT TOTAL_TIME DIST 01 Jan 2018 2,820 6 06 Jan 2018 2,760 6 10 Jan 2018 2,700 6 14 Jan 2018 847 2 Where's my 10 mile run?
  • 114. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | any runs cumulative time < 3,000 and one run cumulative time >= 3,000
  • 115. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( )
  • 116. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( under_fifty* over_fifty )
  • 117. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( under_fifty* over_fifty ) define under_fifty as sum ( time_in_s ) < 3000, over_fifty as sum ( time_in_s ) >= 3000 ); Includes under_fifty values
  • 118. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as strt , sum ( time_in_s ) as total_time, sum ( distance_in_miles ) as dist pattern ( under_fifty* over_fifty ) define under_fifty as sum ( time_in_s ) < 3000, over_fifty as sum ( time_in_s ) >= 3000 );
  • 119. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | STRT TOTAL_TIME DIST 01 Jan 2018 7,752 16 06 Jan 2018 3,160 7 13 Jan 2018 3,147 7 Hmmm….
  • 120. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as strt , sum ( time_in_s ) as total_time, sum ( distance_in_miles ) as dist after match skip past last row pattern ( under_fifty* over_fifty ) define under_fifty as sum ( time_in_s ) < 3000, over_fifty as sum ( time_in_s ) >= 3000 );
  • 121. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as strt , sum ( time_in_s ) as total_time, sum ( distance_in_miles ) as dist after match skip to next row pattern ( under_fifty* over_fifty ) define under_fifty as sum ( time_in_s ) < 3000, over_fifty as sum ( time_in_s ) >= 3000 );
  • 122. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | STRT TOTAL_TIME DIST 01 Jan 2018 7,752 16 02 Jan 2018 7,332 15 03 Jan 2018 4,932 10 06 Jan 2018 3,160 7 07 Jan 2018 3,110 7 10 Jan 2018 3,125 7 13 Jan 2018 3,147 7
  • 123. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Pixabay
  • 124. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | How often did I run 5 miles Followed by 2+ 1 mile runs Within 7 days?
  • 125. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( five_mile one_mile {2,} ) define
  • 126. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( five_mile one_mile {2,} ) define five_mile as distance_in_miles = 5,
  • 127. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( five_mile one_mile {2,} ) define five_mile as distance_in_miles = 5, one_mile as distance_in_miles = 1
  • 128. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | pattern ( five_mile one_mile {2,} ) define five_mile as distance_in_miles = 5, one_mile as distance_in_miles = 1 and run_date < first ( run_date ) + 7
  • 129. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures first ( run_date ) as start_date, count (*) as total_runs pattern ( five_mile one_mile {2,} ) define five_mile as distance_in_miles = 5, one_mile as distance_in_miles = 1 and run_date < first ( run_date ) + 7 );
  • 130. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | STRT TOTAL_RUNS 06 Jan 2018 3 13 Jan 2018 3
  • 131. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Why would I want to do that?!
  • 132. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Pixabay
  • 133. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | How do I debug it? Gratisography
  • 134. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | (Regular) [exprsion]+ are easy to missteak
  • 135. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | regex101.comregex101.com
  • 136. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | classifier => Which variable matched?
  • 137. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | classifier => Which variable matched? match_number => Which group is this?
  • 138. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | classifier => Which variable matched? match_number => Which group is this? all rows per match
  • 139. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | classifier => Which variable matched? match_number => Which group is this? all rows per match with unmatched rows => Show me everything!
  • 140. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | match_recognize ( order by run_date measures classifier () as var, match_number () as grp all rows per match with unmatched rows pattern ( five_mile one_mile {2,} ) define five_mile as distance_in_miles = 5, one_mile as distance_in_miles = 1 and run_date < first ( run_date ) + 7 );
  • 141. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | RUN_DATE VAR GRP TIME_IN_S DISTANCE_IN_MILES 01 Jan 2018 420 1 02 Jan 2018 2,400 5 03 Jan 2018 4,932 10 06 Jan 2018 FIVE_MILE 1 2,350 5 07 Jan 2018 ONE_MILE 1 410 1 10 Jan 2018 ONE_MILE 1 400 1 13 Jan 2018 FIVE_MILE 2 2,300 5 14 Jan 2018 ONE_MILE 2 425 1 15 Jan 2018 ONE_MILE 2 422 1
  • 142. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Want more? Pixabay
  • 143. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. |
  • 144. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | iTunes & PDF FREE! SQL for Data Warehousing and Analytics https://oracle-big-data.blogspot.co.uk Keith Laker Analytic SQL PM
  • 145. Copyright © 2017, Oracle and/or its affiliates. All rights reserved. | Gratisography #MakeDataGreatAgain oracle-big-data.blogspot.co.uk