{"id":14277,"date":"2020-06-08T14:39:55","date_gmt":"2020-06-08T12:39:55","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/"},"modified":"2023-07-18T07:30:23","modified_gmt":"2023-07-18T05:30:23","slug":"oracle-row-pattern","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/","title":{"rendered":"Oracle 12c &#8211; peak detection with MATCH_RECOGNIZE"},"content":{"rendered":"<h2>By Franck Pachot<\/h2>\n<p>.<br \/>\nThis post is part of a series of small examples of recent features. I&#8217;m running this in the Oracle 20c preview in the Oracle Cloud. I&#8217;ll show a very basic example of &#8220;Row Pattern Recognition&#8221; (the MATCH_RECOGNIZE clause in a SELECT which is documented as &#8220;row pattern matching in native SQL&#8221; feature by Oracle&#8221;). You may be afraid of those names. Of course, because SQL is a declarative language there is a small learning curve to get beyond this abstraction. Understanding procedurally how it works may help. But when you understand the declarative nature it is really powerful. This post is there to start simple on a simple table with time series where I just want to detect peaks (the points where the value goes up and then down).<\/p>\n<p>Historically, a SELECT statement was operating on single rows (JOIN, WHERE, SELECT) within a set, or an aggregation of rows (GROUP BY, HAVING) to provide a summary. Analytic functions can operate on windows of rows (PARTITION BY, ORDER BY, ROWS BETWEEN,&#8230;) where you keep the detailed level or rows and compare it to the aggregated values of the group. A row can then look at its neighbours and when needing to go further, the SQL MODEL can build the equivalent of spreadsheet cells to reference other rows and columns. As in a spreadsheet, you can also PIVOT to move row detail to columns or vice versa. All that can be done in SQL, which means that you don&#8217;t code how to do it but just define the result you want. However, there&#8217;s something that is easy to do in a spreadsheet application like Excel but not easy to code with analytic functions: looking at a Chart, as a Line Graph, to detect some behaviour. That&#8217;s something we can code in SQL with MATCH_RECOGNIZE.<\/p>\n<p>For example, from the &#8220;COVID&#8221; table I have imported in the <a href=\"https:\/\/www.dbi-services.com\/blog\/oracle-index-on-joins\/oracle-select-from-file\" target=\"_blank\" rel=\"noopener noreferrer\">previous post<\/a> I want to see each peak of covid-19 cases in Switzerland:<br \/>\n<img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-large wp-image-40488\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled.jpg\" alt=\"\" width=\"1024\" height=\"493\" \/><\/p>\n<p>I did this manually in Excel: showing all labels but keeping only those that are at a peak, whether it is a small peak or high one. There&#8217;s one value per day in this timeseries but I&#8217;m am not interested by the intermediate values. Only peaks. So, this was done from the .csv imported from <a href=\"http:\/\/opendata.ecdc.europa.eu\/covid19\/casedistribution\/csv\/\" target=\"_blank\" rel=\"noopener noreferrer\">http:\/\/opendata.ecdc.europa.eu\/covid19\/casedistribution\/csv\/<\/a> through an external table but, as I imported it into an Oracle table for the previous post (<a href=\"https:\/\/www.dbi-services.com\/blog\/oracle-select-from-file\/\" target=\"_blank\" rel=\"noopener noreferrer\">Oracle 18c \u2013 select from a flat file<\/a>).<\/p>\n<p>Ok, let&#8217;s show directly the result. Here is a small SQL statement that show me exactly those peaks, each match being numbered:<\/p>\n<pre><code>\nSQL&gt; select countriesandterritories \"Country\",\"Peak date\",\"Peak cases\",\"match#\"\n  2  from covid\n  3  match_recognize (\n  4   partition by continentexp, countriesandterritories order by daterep\n  5   measures\n  6    match_number() as \"match#\",\n  7    last(GoingUp.dateRep) as \"Peak date\",\n  8    last(GoingUp.cases) as \"Peak cases\"\n  9   one row per match\n 10   pattern (GoingUp+ GoingDown+)\n 11   define\n 12    GoingUp as ( GoingUp.cases &gt; prev(GoingUp.cases) ),\n 13    GoingDown as ( GoingDown.cases &lt; prev(GoingDown.cases))\n 14  )\n 15  where countriesandterritories='Switzerland';\n\n       Country    Peak date    Peak cases    match#\n______________ ____________ _____________ _________\nSwitzerland    26-FEB-20                1         1\nSwitzerland    28-FEB-20                7         2\nSwitzerland    07-MAR-20              122         3\nSwitzerland    09-MAR-20               68         4\nSwitzerland    14-MAR-20              267         5\nSwitzerland    16-MAR-20              841         6\nSwitzerland    18-MAR-20              450         7\nSwitzerland    22-MAR-20             1237         8\nSwitzerland    24-MAR-20             1044         9\nSwitzerland    28-MAR-20             1390        10\nSwitzerland    31-MAR-20             1138        11\nSwitzerland    03-APR-20             1124        12\nSwitzerland    08-APR-20              590        13\nSwitzerland    10-APR-20              785        14\nSwitzerland    16-APR-20              583        15\nSwitzerland    18-APR-20              346        16\nSwitzerland    20-APR-20              336        17\nSwitzerland    24-APR-20              228        18\nSwitzerland    26-APR-20              216        19\nSwitzerland    01-MAY-20              179        20\nSwitzerland    09-MAY-20               81        21\nSwitzerland    11-MAY-20               54        22\nSwitzerland    17-MAY-20               58        23\nSwitzerland    21-MAY-20               40        24\nSwitzerland    24-MAY-20               18        25\nSwitzerland    27-MAY-20               15        26\nSwitzerland    29-MAY-20               35        27\nSwitzerland    06-JUN-20               23        28\n\n\n28 rows selected.\n\n<\/code><\/pre>\n<p>Doing that with analytic functions or MODEL clause is possible, but not easy.<\/p>\n<p>So let&#8217;s explain the clauses in this simple example.<\/p>\n<h3>Define<\/h3>\n<p>I&#8217;ll need to define what is a peak. For that, I need to define two very primary patterns. The value I&#8217;m looking for, which is the one you see on the graph, is the column &#8220;CASES&#8221;, which is the number of covid-19 cases for the day and country. How do you detect peaks visually? Like when hiking in mountains: it goes up and when you continue it goes down. Here are those two primary patterns:<\/p>\n<pre><code>\n 11   define\n 12    GoingUp as ( GoingUp.cases &gt;= prev(GoingUp.cases) ),\n 13    GoingDown as ( GoingDown.cases &lt; prev(GoingDown.cases))\n<\/code><\/pre>\n<p>&#8220;GoingUp&#8221; matches a row where &#8220;cases&#8221; value is higher than the preceding row and &#8220;GoingDown&#8221; matches a row where &#8220;cases&#8221; is lower than the preceding one. The sense of &#8220;preceding one&#8221;, of course, depends on an order, like with analytic functions. We will see it below.<\/p>\n<h3>Pattern<\/h3>\n<p>A peak is when a row matches GoingDown just after matching GoingUp. That&#8217;s simple but you can imagine crazy things that a data scientist would want to recognize. And then the MATCH_RECOGNIZE defines patterns in a similar way as Regular Expressions: mentioning the primary patterns in a sequence with some modifiers. Mine is so simple:<\/p>\n<pre><code>\n 10   pattern (GoingUp+ GoingDown+)\n<\/code><\/pre>\n<p>This means: one or more GoingUp followed by one or more GoingDown. This is exactly what I did in the graph above: ignore intermediate points. So, the primary pattern compares a row with the preceding only and consecutive comparisons are walked through and compared with the pattern.<\/p>\n<h3>Partition by<\/h3>\n<p>As mentioned, I follow the rows in order. For a timeseries, this is simple: the key is the country here, I partition by continent and country, and the order (x-axis) is the date. I&#8217;m looking at the peaks per country when the value (&#8220;cases&#8221;) is ordered by date (&#8220;daterep&#8221;):<\/p>\n<pre><code>\n  2  from covid\n...\n  4   partition by continentexp, countriesandterritories order by daterep\n...\n 15* where countriesandterritories='Switzerland';\n<\/code><\/pre>\n<p>I selected only my country here with a standard where clause, to show simple things.<\/p>\n<h3>Measures<\/h3>\n<p>Eatch time a pattern is recognized, I want to display only one row (&#8220;ONE ROW PER MATCH&#8221;) with some measures for it. Of course, I must access to the point I&#8217;m interested in: the x-axis date and y-axis value for it. I can reference points within the matching window and I use the pattern variables to reference them. The peak is the last row in the &#8220;GoingUp&#8221; primary pattern and last(GoingUp.dateRep) and last(GoingUp.cases) are my points:<\/p>\n<pre><code>\n  5   measures\n  6    match_number() as \"match#\",\n  7    last(GoingUp.dateRep) as \"Peak date\",\n  8    last(GoingUp.cases) as \"Peak cases\"\n  9   one row per match\n<\/code><\/pre>\n<p>Those measures are accessible in the SELECT clause of my SQL statement. I added the match_number() to identify the points.<\/p>\n<p>Here is the final query, with the partition, measures, pattern and define clauses within the MATCH_RECOGNIZE():<\/p>\n<pre><code>\nselect countriesandterritories \"Country\",\"Peak date\",\"Peak cases\",\"match#\"\nfrom covid\nmatch_recognize (\n partition by continentexp, countriesandterritories order by daterep\n measures\n  match_number() as \"match#\",\n  last(GoingUp.dateRep) as \"Peak date\",\n  last(GoingUp.cases) as \"Peak cases\"\n one row per match\n pattern (GoingUp+ GoingDown+)\n define\n  GoingUp as ( GoingUp.cases &gt; prev(GoingUp.cases) ),\n  GoingDown as ( GoingDown.cases &lt; prev(GoingDown.cases))\n)\nwhere countriesandterritories='Switzerland';\n<\/code><\/pre>\n<p>The full syntax can have more and of course all is documented: <a href=\"https:\/\/docs.oracle.com\/database\/121\/DWHSG\/pattern.htm#DWHSG8982\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/docs.oracle.com\/database\/121\/DWHSG\/pattern.htm#DWHSG8982<\/a><\/p>\n<h3>Debug mode<\/h3>\n<p>In order to understand how it works (and debug) we can display &#8220;all rows&#8221; (ALL ROWS PER MATCH instead of ONE ROW PER MATCH in line 9), and add the row columns (DATEREP and CASES in line 1) and, in addition to the match_number() I have added the classifier() measure:<\/p>\n<pre><code>\n  1  select countriesandterritories \"Country\",\"Peak date\",\"Peak cases\",\"match#\",daterep,cases,\"classifier\"\n  2  from covid\n  3  match_recognize (\n  4   partition by continentexp, countriesandterritories order by daterep\n  5   measures\n  6    match_number() as \"match#\", classifier() as \"classifier\",\n  7    last(GoingUp.dateRep) as \"Peak date\",\n  8    last(GoingUp.cases) as \"Peak cases\"\n  9   all rows per match\n 10   pattern (GoingUp+ GoingDown+)\n 11   define\n 12    GoingUp as ( GoingUp.cases &gt; prev(GoingUp.cases) ),\n 13    GoingDown as ( GoingDown.cases &lt; prev(GoingDown.cases))\n 14  )\n 15* where countriesandterritories='Switzerland';\n<\/code><\/pre>\n<p>&#8220;all rows per match&#8221; shows all rows where pattern matching is tested, classifier() shows which primary pattern is matched.<\/p>\n<p>Here are the rows around the 10th match. You must keep in mind that rows are processed in order and for each row, it looks ahead to recognize a pattern.<\/p>\n<pre><code>\n       Country    Peak date    Peak cases    match#      DATEREP    CASES    classifier\n______________ ____________ _____________ _________ ____________ ________ _____________\n...\nSwitzerland    24-MAR-20             1044         9 24-MAR-20        1044 GOINGUP\nSwitzerland    24-MAR-20             1044         9 25-MAR-20         774 GOINGDOWN\nSwitzerland    26-MAR-20              925        10 26-MAR-20         925 GOINGUP\nSwitzerland    27-MAR-20             1000        10 27-MAR-20        1000 GOINGUP\nSwitzerland    28-MAR-20             1390        10 28-MAR-20        1390 GOINGUP\nSwitzerland    28-MAR-20             1390        10 29-MAR-20        1048 GOINGDOWN\nSwitzerland    30-MAR-20             1122        11 30-MAR-20        1122 GOINGUP\nSwitzerland    31-MAR-20             1138        11 31-MAR-20        1138 GOINGUP              \nSwitzerland    31-MAR-20             1138        11 01-APR-20         696 GOINGDOWN  \nSwitzerland    02-APR-20              962        12 02-APR-20         962 GOINGUP\nSwitzerland    03-APR-20             1124        12 03-APR-20        1124 GOINGUP\nSwitzerland    03-APR-20             1124        12 04-APR-20        1033 GOINGDOWN\n<\/code><\/pre>\n<p>You see here how we came to output the 10th matched (28-MAR-20 1390 cases). After the peak of 24-MAR-20 we were going down the next day 25-MAR-20 (look at the graph). This was included in the 10th match because of regular expression &#8220;GoingDown+&#8221;. Then up 26-MAR-2020 to 28-MAR-20, which matches GoingUp+ followed by a &#8220;GoingDown&#8221; on 29-MAR-20 which means that a 11th match has been recognized. It continues for all &#8220;GoingDown+&#8221; but there&#8217;s only one here as the next one is a higher value: 1122 &gt; 1048 so the 11th match is closed here on 29-MAR-20. This is where the ONE ROW PER MATCH is returned, when processing the row from 29-MAR-20, with the values from the last row classified as GOINGUP, and defined in the measures, which are 28-MAR-20 and 1390. And then the pattern matching continues from this row and a GoingUp has been detected&#8230;<\/p>\n<p>If you want to go further, there are good examples from Lucas Jellama: <a href=\"https:\/\/technology.amis.nl\/?s=match_recognize\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/technology.amis.nl\/?s=match_recognize<\/a><br \/>\nAnd about its implementation in SQL engines, read Markus Winand <a href=\"https:\/\/modern-sql.com\/feature\/match_recognize\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/modern-sql.com\/feature\/match_recognize<\/a><\/p>\n<p>And I&#8217;ll probably have more blog posts here in this series about recent features interesting for BI and DWH&#8230;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>By Franck Pachot . This post is part of a series of small examples of recent features. I&#8217;m running this in the Oracle 20c preview in the Oracle Cloud. I&#8217;ll show a very basic example of &#8220;Row Pattern Recognition&#8221; (the MATCH_RECOGNIZE clause in a SELECT which is documented as &#8220;row pattern matching in native SQL&#8221; [&hellip;]<\/p>\n","protected":false},"author":27,"featured_media":14279,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[955,229,59],"tags":[958,496,1489,1949,1985,96,209,458,1986,1987,1988,1989],"type_dbi":[],"class_list":["post-14277","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cloud","category-database-administration-monitoring","category-oracle","tag-12cr2","tag-bi","tag-dwh","tag-features","tag-matching","tag-oracle","tag-oracle-12c","tag-oracle-20c","tag-pattern","tag-recognition","tag-regexp","tag-row"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Oracle 12c - peak detection with MATCH_RECOGNIZE - dbi Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Oracle 12c - peak detection with MATCH_RECOGNIZE\" \/>\n<meta property=\"og:description\" content=\"By Franck Pachot . This post is part of a series of small examples of recent features. I&#8217;m running this in the Oracle 20c preview in the Oracle Cloud. I&#8217;ll show a very basic example of &#8220;Row Pattern Recognition&#8221; (the MATCH_RECOGNIZE clause in a SELECT which is documented as &#8220;row pattern matching in native SQL&#8221; [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-06-08T12:39:55+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-07-18T05:30:23+00:00\" \/>\n<meta property=\"og:image\" content=\"http:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"2048\" \/>\n\t<meta property=\"og:image:height\" content=\"986\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Oracle Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Oracle Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/\"},\"author\":{\"name\":\"Oracle Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"headline\":\"Oracle 12c &#8211; peak detection with MATCH_RECOGNIZE\",\"datePublished\":\"2020-06-08T12:39:55+00:00\",\"dateModified\":\"2023-07-18T05:30:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/\"},\"wordCount\":1216,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg\",\"keywords\":[\"12cR2\",\"BI\",\"DWH\",\"features\",\"matching\",\"Oracle\",\"Oracle 12c\",\"Oracle 20c\",\"pattern\",\"recognition\",\"regexp\",\"row\"],\"articleSection\":[\"Cloud\",\"Database Administration &amp; Monitoring\",\"Oracle\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/\",\"name\":\"Oracle 12c - peak detection with MATCH_RECOGNIZE - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg\",\"datePublished\":\"2020-06-08T12:39:55+00:00\",\"dateModified\":\"2023-07-18T05:30:23+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#primaryimage\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg\",\"contentUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg\",\"width\":2048,\"height\":986},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Oracle 12c &#8211; peak detection with MATCH_RECOGNIZE\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee\",\"name\":\"Oracle Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g\",\"caption\":\"Oracle Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Oracle 12c - peak detection with MATCH_RECOGNIZE - dbi Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/","og_locale":"en_US","og_type":"article","og_title":"Oracle 12c - peak detection with MATCH_RECOGNIZE","og_description":"By Franck Pachot . This post is part of a series of small examples of recent features. I&#8217;m running this in the Oracle 20c preview in the Oracle Cloud. I&#8217;ll show a very basic example of &#8220;Row Pattern Recognition&#8221; (the MATCH_RECOGNIZE clause in a SELECT which is documented as &#8220;row pattern matching in native SQL&#8221; [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/","og_site_name":"dbi Blog","article_published_time":"2020-06-08T12:39:55+00:00","article_modified_time":"2023-07-18T05:30:23+00:00","og_image":[{"width":2048,"height":986,"url":"http:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg","type":"image\/jpeg"}],"author":"Oracle Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Oracle Team","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/"},"author":{"name":"Oracle Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"headline":"Oracle 12c &#8211; peak detection with MATCH_RECOGNIZE","datePublished":"2020-06-08T12:39:55+00:00","dateModified":"2023-07-18T05:30:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/"},"wordCount":1216,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg","keywords":["12cR2","BI","DWH","features","matching","Oracle","Oracle 12c","Oracle 20c","pattern","recognition","regexp","row"],"articleSection":["Cloud","Database Administration &amp; Monitoring","Oracle"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/","url":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/","name":"Oracle 12c - peak detection with MATCH_RECOGNIZE - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg","datePublished":"2020-06-08T12:39:55+00:00","dateModified":"2023-07-18T05:30:23+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/12c_match_recognize-scaled-1.jpg","width":2048,"height":986},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/oracle-row-pattern\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Oracle 12c &#8211; peak detection with MATCH_RECOGNIZE"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/66ab87129f2d357f09971bc7936a77ee","name":"Oracle Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f711f7cd2c9b09bf2627133755b569fb5be0694810cfd33033bdd095fedba86d?s=96&d=mm&r=g","caption":"Oracle Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/oracle-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/14277","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=14277"}],"version-history":[{"count":1,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/14277\/revisions"}],"predecessor-version":[{"id":26796,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/14277\/revisions\/26796"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media\/14279"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=14277"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=14277"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=14277"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=14277"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}