Pattern Matching (MATCH_RECOGNIZE) in Oracle Database 12c Release 1 (12.1)
Learn about the new pattern matching analytic function clause available in Oracle 12c onward.
oracle 12cconfigurationintermediate
by OracleDba
17 views
Learn about the new pattern matching analytic function clause available in Oracle 12c onward.
12345678910111213141516171819202122232425262728293031323334353637383940414243
PARTITION BY product
ORDER BY tstamp
MEASURES STRT.tstamp AS start_tstamp,
LAST(UP.tstamp) AS peak_tstamp,
LAST(DOWN.tstamp) AS end_tstamp
[ONE ROW | ALL ROWS] PER MATCH
DEFINE
UP AS UP.units_sold > PREV(UP.units_sold),
FLAT AS FLAT.units_sold = PREV(FLAT.units_sold),
DOWN AS DOWN.units_sold < PREV(DOWN.units_sold)
DEFINE
TWINKIES AS TWINKIES.product='TWINKIES',
DINGDONGS AS DINGDONG.product='DINGDONGS',
HOHOS AS HOHOS.product='HOHOS'
-- 1-Many increases, followed by 1-Many decreases in a value. A "V" shaped spike.
PATTERN (STRT UP+ DOWN+)
-- 1-Many increases, followed by a single decrease, then 1-Many increases. A single dip, during the rise.
PATTERN (STRT UP+ DOWN{1} UP+)
-- 1-5 Twinkies, followed by 1 DingDong, followed by 2 HoHos.
PATTERN(STRT TWINKIES{1,5} DINGDONGS{1} HOHOS{2})
PREV(UP.units_sold) -- Value of units_sold from previous row.
PREV(UP.units_sold, 2) -- Value of units_sold from the row before the previous row (offset of 2 rows).
NEXT(UP.units_sold) -- Value of units_sold from the next row.
NEXT(UP.units_sold, 2) -- Value of units_sold from the row after the following row (offset of 2 rows).
FIRST(UP.units_sold) -- First row in the pattern.
FIRST(UP.units_sold, 1) -- Row following the first row (offset of 1 row).
LAST(UP.units_sold) -- Last row in the pattern.
LAST(UP.units_sold, 1) -- Row preceding the last row (offset of 1 row).123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
DROP TABLE sales_history PURGE;
CREATE TABLE sales_history (
id NUMBER,
product VARCHAR2(20),
tstamp TIMESTAMP,
units_sold NUMBER,
CONSTRAINT sales_history_pk PRIMARY KEY (id)
);
ALTER SESSION SET nls_timestamp_format = 'DD-MON-YYYY';
INSERT INTO sales_history VALUES ( 1, 'TWINKIES', '01-OCT-2014', 17);
INSERT INTO sales_history VALUES ( 2, 'TWINKIES', '02-OCT-2014', 19);
INSERT INTO sales_history VALUES ( 3, 'TWINKIES', '03-OCT-2014', 23);
INSERT INTO sales_history VALUES ( 4, 'TWINKIES', '04-OCT-2014', 23);
INSERT INTO sales_history VALUES ( 5, 'TWINKIES', '05-OCT-2014', 16);
INSERT INTO sales_history VALUES ( 6, 'TWINKIES', '06-OCT-2014', 10);
INSERT INTO sales_history VALUES ( 7, 'TWINKIES', '07-OCT-2014', 14);
INSERT INTO sales_history VALUES ( 8, 'TWINKIES', '08-OCT-2014', 16);
INSERT INTO sales_history VALUES ( 9, 'TWINKIES', '09-OCT-2014', 15);
INSERT INTO sales_history VALUES (10, 'TWINKIES', '10-OCT-2014', 17);
INSERT INTO sales_history VALUES (11, 'TWINKIES', '11-OCT-2014', 23);
INSERT INTO sales_history VALUES (12, 'TWINKIES', '12-OCT-2014', 30);
INSERT INTO sales_history VALUES (13, 'TWINKIES', '13-OCT-2014', 31);
INSERT INTO sales_history VALUES (14, 'TWINKIES', '14-OCT-2014', 29);
INSERT INTO sales_history VALUES (15, 'TWINKIES', '15-OCT-2014', 25);
INSERT INTO sales_history VALUES (16, 'TWINKIES', '16-OCT-2014', 21);
INSERT INTO sales_history VALUES (17, 'TWINKIES', '17-OCT-2014', 35);
INSERT INTO sales_history VALUES (18, 'TWINKIES', '18-OCT-2014', 46);
INSERT INTO sales_history VALUES (19, 'TWINKIES', '19-OCT-2014', 45);
INSERT INTO sales_history VALUES (20, 'TWINKIES', '20-OCT-2014', 30);
COMMIT;
ALTER SESSION SET nls_timestamp_format = 'DD-MON-YYYY';
SET PAGESIZE 50
COLUMN product FORMAT A10
COLUMN tstamp FORMAT A11
COLUMN graph FORMAT A50
SELECT id,
product,
tstamp,
units_sold,
RPAD('#', units_sold, '#') AS graph
FROM sales_history
ORDER BY id;
ID PRODUCT TSTAMP UNITS_SOLD GRAPH
---------- ---------- ----------- ---------- --------------------------------------------------
1 TWINKIES 01-OCT-2014 17 #################
2 TWINKIES 02-OCT-2014 19 ###################
3 TWINKIES 03-OCT-2014 23 #######################
4 TWINKIES 04-OCT-2014 23 #######################
5 TWINKIES 05-OCT-2014 16 ################
6 TWINKIES 06-OCT-2014 10 ##########
7 TWINKIES 07-OCT-2014 14 ##############
8 TWINKIES 08-OCT-2014 16 ################
9 TWINKIES 09-OCT-2014 15 ###############
10 TWINKIES 10-OCT-2014 17 #################
11 TWINKIES 11-OCT-2014 23 #######################
12 TWINKIES 12-OCT-2014 30 ##############################
13 TWINKIES 13-OCT-2014 31 ###############################
14 TWINKIES 14-OCT-2014 29 #############################
15 TWINKIES 15-OCT-2014 25 #########################
16 TWINKIES 16-OCT-2014 21 #####################
17 TWINKIES 17-OCT-2014 35 ###################################
18 TWINKIES 18-OCT-2014 46 ##############################################
19 TWINKIES 19-OCT-2014 45 #############################################
20 TWINKIES 20-OCT-2014 30 ##############################
20 rows selected.
SQL>
DROP TABLE sales_audit PURGE;
CREATE TABLE sales_audit (
id NUMBER,
product VARCHAR2(20),
tstamp TIMESTAMP,
CONSTRAINT sales_audit_pk PRIMARY KEY (id)
);
ALTER SESSION SET nls_timestamp_format = 'DD-MON-YYYY HH24:MI:SS';
INSERT INTO sales_audit VALUES ( 1, 'TWINKIES', '01-OCT-2014 12:00:01');
INSERT INTO sales_audit VALUES ( 2, 'TWINKIES', '01-OCT-2014 12:00:02');
INSERT INTO sales_audit VALUES ( 3, 'DINGDONGS', '01-OCT-2014 12:00:03');
INSERT INTO sales_audit VALUES ( 4, 'HOHOS', '01-OCT-2014 12:00:04');
INSERT INTO sales_audit VALUES ( 5, 'HOHOS', '01-OCT-2014 12:00:05');
INSERT INTO sales_audit VALUES ( 6, 'TWINKIES', '01-OCT-2014 12:00:06');
INSERT INTO sales_audit VALUES ( 7, 'TWINKIES', '01-OCT-2014 12:00:07');
INSERT INTO sales_audit VALUES ( 8, 'DINGDONGS', '01-OCT-2014 12:00:08');
INSERT INTO sales_audit VALUES ( 9, 'DINGDONGS', '01-OCT-2014 12:00:09');
INSERT INTO sales_audit VALUES (10, 'HOHOS', '01-OCT-2014 12:00:10');
INSERT INTO sales_audit VALUES (11, 'HOHOS', '01-OCT-2014 12:00:11');
INSERT INTO sales_audit VALUES (12, 'TWINKIES', '01-OCT-2014 12:00:12');
INSERT INTO sales_audit VALUES (13, 'TWINKIES', '01-OCT-2014 12:00:13');
INSERT INTO sales_audit VALUES (14, 'DINGDONGS', '01-OCT-2014 12:00:14');
INSERT INTO sales_audit VALUES (15, 'DINGDONGS', '01-OCT-2014 12:00:15');
INSERT INTO sales_audit VALUES (16, 'HOHOS', '01-OCT-2014 12:00:16');
INSERT INTO sales_audit VALUES (17, 'TWINKIES', '01-OCT-2014 12:00:17');
INSERT INTO sales_audit VALUES (18, 'TWINKIES', '01-OCT-2014 12:00:18');
INSERT INTO sales_audit VALUES (19, 'TWINKIES', '01-OCT-2014 12:00:19');
INSERT INTO sales_audit VALUES (20, 'TWINKIES', '01-OCT-2014 12:00:20');
COMMIT;
COLUMN tstamp FORMAT A20
SELECT *
FROM sales_audit
ORDER BY tstamp;
ID PRODUCT TSTAMP
---------- ---------- --------------------
1 TWINKIES 01-OCT-2014 12:00:01
2 TWINKIES 01-OCT-2014 12:00:02
3 DINGDONG 01-OCT-2014 12:00:03
4 HOHOS 01-OCT-2014 12:00:04
5 HOHOS 01-OCT-2014 12:00:05
6 TWINKIES 01-OCT-2014 12:00:06
7 TWINKIES 01-OCT-2014 12:00:07
8 DINGDONGS 01-OCT-2014 12:00:08
9 DINGDONGS 01-OCT-2014 12:00:09
10 HOHOS 01-OCT-2014 12:00:10
11 HOHOS 01-OCT-2014 12:00:11
12 TWINKIES 01-OCT-2014 12:00:12
13 TWINKIES 01-OCT-2014 12:00:13
14 DINDONGS 01-OCT-2014 12:00:14
15 HOHOS 01-OCT-2014 12:00:15
16 TWINKIES 01-OCT-2014 12:00:16
17 TWINKIES 01-OCT-2014 12:00:17
18 TWINKIES 01-OCT-2014 12:00:18
19 TWINKIES 01-OCT-2014 12:00:19
20 TWINKIES 01-OCT-2014 12:00:20
20 rows selected.
SQL>123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
ALTER SESSION SET nls_timestamp_format = 'DD-MON-YYYY';
COLUMN start_tstamp FORMAT A11
COLUMN peak_tstamp FORMAT A11
COLUMN end_tstamp FORMAT A11
SELECT *
FROM sales_history MATCH_RECOGNIZE (
PARTITION BY product
ORDER BY tstamp
MEASURES STRT.tstamp AS start_tstamp,
LAST(UP.tstamp) AS peak_tstamp,
LAST(DOWN.tstamp) AS end_tstamp,
MATCH_NUMBER() AS mno
ONE ROW PER MATCH
AFTER MATCH SKIP TO LAST DOWN
PATTERN (STRT UP+ FLAT* DOWN+)
DEFINE
UP AS UP.units_sold > PREV(UP.units_sold),
FLAT AS FLAT.units_sold = PREV(FLAT.units_sold),
DOWN AS DOWN.units_sold < PREV(DOWN.units_sold)
) MR
ORDER BY MR.product, MR.start_tstamp;
PRODUCT START_TSTAM PEAK_TSTAMP END_TSTAMP MNO
---------- ----------- ----------- ----------- ----------
TWINKIES 01-OCT-2014 03-OCT-2014 06-OCT-2014 1
TWINKIES 06-OCT-2014 08-OCT-2014 09-OCT-2014 2
TWINKIES 09-OCT-2014 13-OCT-2014 16-OCT-2014 3
TWINKIES 16-OCT-2014 18-OCT-2014 20-OCT-2014 4
4 rows selected.
SQL>
SET LINESIZE 110
ALTER SESSION SET nls_timestamp_format = 'DD-MON-YYYY';
COLUMN start_tstamp FORMAT A11
COLUMN peak_tstamp FORMAT A11
COLUMN end_tstamp FORMAT A11
COLUMN cls FORMAT A5
SELECT *
FROM sales_history MATCH_RECOGNIZE (
PARTITION BY product
ORDER BY tstamp
MEASURES STRT.tstamp AS start_tstamp,
FINAL LAST(UP.tstamp) AS peak_tstamp,
FINAL LAST(DOWN.tstamp) AS end_tstamp,
MATCH_NUMBER() AS mno,
CLASSIFIER() AS cls
ALL ROWS PER MATCH
AFTER MATCH SKIP TO LAST DOWN
PATTERN (STRT UP+ FLAT* DOWN+)
DEFINE
UP AS UP.units_sold > PREV(UP.units_sold),
DOWN AS DOWN.units_sold < PREV(DOWN.units_sold),
FLAT AS FLAT.units_sold = PREV(FLAT.units_sold)
) MR
ORDER BY MR.product, MR.mno, MR.tstamp;
PRODUCT TSTAMP START_TSTAM PEAK_TSTAMP END_TSTAMP MNO CLS ID UNITS_SOLD
---------- ----------- ----------- ----------- ----------- ---------- ----- ---------- ----------
TWINKIES 01-OCT-2014 01-OCT-2014 03-OCT-2014 06-OCT-2014 1 STRT 1 17
TWINKIES 02-OCT-2014 01-OCT-2014 03-OCT-2014 06-OCT-2014 1 UP 2 19
TWINKIES 03-OCT-2014 01-OCT-2014 03-OCT-2014 06-OCT-2014 1 UP 3 23
TWINKIES 04-OCT-2014 01-OCT-2014 03-OCT-2014 06-OCT-2014 1 FLAT 4 23
TWINKIES 05-OCT-2014 01-OCT-2014 03-OCT-2014 06-OCT-2014 1 DOWN 5 16
TWINKIES 06-OCT-2014 01-OCT-2014 03-OCT-2014 06-OCT-2014 1 DOWN 6 10
TWINKIES 06-OCT-2014 06-OCT-2014 08-OCT-2014 09-OCT-2014 2 STRT 6 10
TWINKIES 07-OCT-2014 06-OCT-2014 08-OCT-2014 09-OCT-2014 2 UP 7 14
TWINKIES 08-OCT-2014 06-OCT-2014 08-OCT-2014 09-OCT-2014 2 UP 8 16
TWINKIES 09-OCT-2014 06-OCT-2014 08-OCT-2014 09-OCT-2014 2 DOWN 9 15
TWINKIES 09-OCT-2014 09-OCT-2014 13-OCT-2014 16-OCT-2014 3 STRT 9 15
TWINKIES 10-OCT-2014 09-OCT-2014 13-OCT-2014 16-OCT-2014 3 UP 10 17
TWINKIES 11-OCT-2014 09-OCT-2014 13-OCT-2014 16-OCT-2014 3 UP 11 23
TWINKIES 12-OCT-2014 09-OCT-2014 13-OCT-2014 16-OCT-2014 3 UP 12 30
TWINKIES 13-OCT-2014 09-OCT-2014 13-OCT-2014 16-OCT-2014 3 UP 13 31
TWINKIES 14-OCT-2014 09-OCT-2014 13-OCT-2014 16-OCT-2014 3 DOWN 14 29
TWINKIES 15-OCT-2014 09-OCT-2014 13-OCT-2014 16-OCT-2014 3 DOWN 15 25
TWINKIES 16-OCT-2014 09-OCT-2014 13-OCT-2014 16-OCT-2014 3 DOWN 16 21
TWINKIES 16-OCT-2014 16-OCT-2014 18-OCT-2014 20-OCT-2014 4 STRT 16 21
TWINKIES 17-OCT-2014 16-OCT-2014 18-OCT-2014 20-OCT-2014 4 UP 17 35
TWINKIES 18-OCT-2014 16-OCT-2014 18-OCT-2014 20-OCT-2014 4 UP 18 46
TWINKIES 19-OCT-2014 16-OCT-2014 18-OCT-2014 20-OCT-2014 4 DOWN 19 45
TWINKIES 20-OCT-2014 16-OCT-2014 18-OCT-2014 20-OCT-2014 4 DOWN 20 30
23 rows selected.
SQL>
SELECT *
FROM sales_history MATCH_RECOGNIZE (
PARTITION BY product
ORDER BY tstamp
MEASURES STRT.tstamp AS start_tstamp,
FINAL LAST(UP.tstamp) AS peak_tstamp,
MATCH_NUMBER() AS mno,
CLASSIFIER() AS cls
ALL ROWS PER MATCH
AFTER MATCH SKIP TO LAST DOWN
PATTERN (STRT UP+ DOWN{1} UP+)
DEFINE
UP AS UP.units_sold > PREV(UP.units_sold),
DOWN AS DOWN.units_sold < PREV(DOWN.units_sold)
) MR
ORDER BY MR.product, MR.tstamp;
PRODUCT TSTAMP START_TSTAM PEAK_TSTAMP MNO CLS ID UNITS_SOLD
---------- ----------- ----------- ----------- ---------- ----- ---------- ----------
TWINKIES 06-OCT-2014 06-OCT-2014 13-OCT-2014 1 STRT 6 10
TWINKIES 07-OCT-2014 06-OCT-2014 13-OCT-2014 1 UP 7 14
TWINKIES 08-OCT-2014 06-OCT-2014 13-OCT-2014 1 UP 8 16
TWINKIES 09-OCT-2014 06-OCT-2014 13-OCT-2014 1 DOWN 9 15
TWINKIES 10-OCT-2014 06-OCT-2014 13-OCT-2014 1 UP 10 17
TWINKIES 11-OCT-2014 06-OCT-2014 13-OCT-2014 1 UP 11 23
TWINKIES 12-OCT-2014 06-OCT-2014 13-OCT-2014 1 UP 12 30
TWINKIES 13-OCT-2014 06-OCT-2014 13-OCT-2014 1 UP 13 31
8 rows selected.
SQL>
ALTER SESSION SET nls_timestamp_format = 'DD-MON-YYYY HH24:MI:SS';
COLUMN tstamp FORMAT A20
COLUMN start_tstamp FORMAT A20
COLUMN end_tstamp FORMAT A20
COLUMN cls FORMAT A10
SELECT *
FROM sales_audit MATCH_RECOGNIZE (
--PARTITION BY product
ORDER BY tstamp
MEASURES FIRST(TWINKIES.tstamp) AS start_tstamp,
FINAL LAST(TWINKIES.tstamp) AS end_tstamp,
MATCH_NUMBER() AS mno,
CLASSIFIER() AS cls
ALL ROWS PER MATCH
AFTER MATCH SKIP TO LAST TWINKIES
PATTERN(TWINKIES{2,} DINGDONGS{2} HOHOS{1} TWINKIES{3,})
DEFINE
TWINKIES AS TWINKIES.product='TWINKIES',
DINGDONGS AS DINGDONGS.product='DINGDONGS',
HOHOS AS HOHOS.product='HOHOS'
) MR
ORDER BY MR.mno, MR.tstamp;
TSTAMP START_TSTAMP END_TSTAMP MNO CLS ID PRODUCT
-------------------- -------------------- -------------------- ---------- ---------- ---------- ----------
01-OCT-2014 12:00:12 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 TWINKIES 12 TWINKIES
01-OCT-2014 12:00:13 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 TWINKIES 13 TWINKIES
01-OCT-2014 12:00:14 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 DINGDONGS 14 DINGDONGS
01-OCT-2014 12:00:15 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 DINGDONGS 15 DINGDONGS
01-OCT-2014 12:00:16 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 HOHOS 16 HOHOS
01-OCT-2014 12:00:17 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 TWINKIES 17 TWINKIES
01-OCT-2014 12:00:18 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 TWINKIES 18 TWINKIES
01-OCT-2014 12:00:19 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 TWINKIES 19 TWINKIES
01-OCT-2014 12:00:20 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 1 TWINKIES 20 TWINKIES
9 rows selected.
SQL>
SELECT *
FROM sales_audit MATCH_RECOGNIZE (
--PARTITION BY product
ORDER BY tstamp
MEASURES FIRST(TWINKIES.tstamp) AS start_tstamp,
FINAL LAST(TWINKIES.tstamp) AS end_tstamp,
MATCH_NUMBER() AS mno,
CLASSIFIER() AS cls
ALL ROWS PER MATCH
AFTER MATCH SKIP TO LAST TWINKIES
PATTERN(TWINKIES+ (DINGDONGS | HOHOS){3} TWINKIES+)
DEFINE
TWINKIES AS TWINKIES.product='TWINKIES',
DINGDONGS AS DINGDONGS.product='DINGDONGS',
HOHOS AS HOHOS.product='HOHOS'
) MR
ORDER BY MR.mno, MR.tstamp;
TSTAMP START_TSTAMP END_TSTAMP MNO CLS ID PRODUCT
-------------------- -------------------- -------------------- ---------- ---------- ---------- ----------
01-OCT-2014 12:00:01 01-OCT-2014 12:00:01 01-OCT-2014 12:00:07 1 TWINKIES 1 TWINKIES
01-OCT-2014 12:00:02 01-OCT-2014 12:00:01 01-OCT-2014 12:00:07 1 TWINKIES 2 TWINKIES
01-OCT-2014 12:00:03 01-OCT-2014 12:00:01 01-OCT-2014 12:00:07 1 DINGDONGS 3 DINGDONGS
01-OCT-2014 12:00:04 01-OCT-2014 12:00:01 01-OCT-2014 12:00:07 1 HOHOS 4 HOHOS
01-OCT-2014 12:00:05 01-OCT-2014 12:00:01 01-OCT-2014 12:00:07 1 HOHOS 5 HOHOS
01-OCT-2014 12:00:06 01-OCT-2014 12:00:01 01-OCT-2014 12:00:07 1 TWINKIES 6 TWINKIES
01-OCT-2014 12:00:07 01-OCT-2014 12:00:01 01-OCT-2014 12:00:07 1 TWINKIES 7 TWINKIES
01-OCT-2014 12:00:12 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 TWINKIES 12 TWINKIES
01-OCT-2014 12:00:13 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 TWINKIES 13 TWINKIES
01-OCT-2014 12:00:14 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 DINGDONGS 14 DINGDONGS
01-OCT-2014 12:00:15 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 DINGDONGS 15 DINGDONGS
01-OCT-2014 12:00:16 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 HOHOS 16 HOHOS
01-OCT-2014 12:00:17 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 TWINKIES 17 TWINKIES
01-OCT-2014 12:00:18 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 TWINKIES 18 TWINKIES
01-OCT-2014 12:00:19 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 TWINKIES 19 TWINKIES
01-OCT-2014 12:00:20 01-OCT-2014 12:00:12 01-OCT-2014 12:00:20 2 TWINKIES 20 TWINKIES
16 rows selected.
SQL>Please to add comments
No comments yet. Be the first to comment!