<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OpenText Analytics Database 26.2.x – SQL analytics</title>
    <link>/en/data-analysis/sql-analytics/</link>
    <description>Recent content in SQL analytics on OpenText Analytics Database 26.2.x</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/en/data-analysis/sql-analytics/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Data-Analysis: Invoking analytic functions</title>
      <link>/en/data-analysis/sql-analytics/invoking-analytic-functions/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/invoking-analytic-functions/</guid>
      <description>
        
        
        &lt;p&gt;You invoke analytic functions as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&lt;span class=&#34;code-variable&#34;&gt;analytic-function&lt;/span&gt;(&lt;span class=&#34;code-variable&#34;&gt;arguments&lt;/span&gt;) OVER(
  [ &lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-partition-clause/#&#34;&gt;window-partition-clause&lt;/a&gt;&lt;/span&gt; ]
  [ &lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-order-clause/#&#34;&gt;window-order-clause&lt;/a&gt;&lt;/span&gt; [ &lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-frame-clause/#&#34;&gt;window-frame-clause&lt;/a&gt;&lt;/span&gt; ] ]
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;An analytic function&#39;s &lt;code&gt;OVER&lt;/code&gt; clause contains up to three sub-clauses, which specify how to partition and sort function input, and how to frame input with respect to the current row. Function input is the result set that the query returns after it evaluates &lt;code&gt;FROM&lt;/code&gt;, &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;GROUP BY&lt;/code&gt;, and &lt;code&gt;HAVING&lt;/code&gt; clauses.

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

Each function has its own &lt;code&gt;OVER&lt;/code&gt; clause requirements. For example, some analytic functions do not support window order and window frame clauses.

&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;For syntax details, see &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/#&#34;&gt;Analytic functions&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;function-execution&#34;&gt;Function execution&lt;/h2&gt;
&lt;p&gt;An analytic function executes as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Takes the input rows that the query returns after it performs all joins, and evaluates &lt;code&gt;FROM&lt;/code&gt;, &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;GROUP BY&lt;/code&gt;, and &lt;code&gt;HAVING&lt;/code&gt; clauses.&lt;/li&gt;
&lt;li&gt;Groups input rows according to the window partition (&lt;code&gt;PARTITION BY&lt;/code&gt;) clause. If this clause is omitted, all input rows are treated as a single partition.&lt;/li&gt;
&lt;li&gt;Sorts rows within each partition according to window order (&lt;code&gt;ORDER BY&lt;/code&gt;) clause.&lt;/li&gt;
&lt;li&gt;If the &lt;code&gt;OVER&lt;/code&gt; clause includes a window order clause, the function checks for a window frame clause and executes it as it processes each input row. If the &lt;code&gt;OVER&lt;/code&gt; clause omits a window frame clause, the function treats the entire partition as a window frame.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;restrictions&#34;&gt;Restrictions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Analytic functions are allowed only in a query&#39;s &lt;code&gt;SELECT&lt;/code&gt; and &lt;code&gt;ORDER BY&lt;/code&gt; clauses.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Analytic functions cannot be nested. For example, the following query throws an error:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT MEDIAN(RANK() OVER(ORDER BY sal) OVER()).
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Analytic functions versus aggregate functions</title>
      <link>/en/data-analysis/sql-analytics/analytic-functions-versus-aggregate-functions/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/analytic-functions-versus-aggregate-functions/</guid>
      <description>
        
        
        &lt;p&gt;Like aggregate functions, analytic functions return aggregate results, but analytics do not group the result set. Instead, they return the group value multiple times with each record, allowing further analysis.&lt;/p&gt;
&lt;p&gt;Analytic queries generally run faster and use fewer resources than aggregate queries.

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;th &gt;
Aggregate functions&lt;/th&gt; 

&lt;th &gt;
Analytic functions&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;


Return a single summary value.&lt;/td&gt; 

&lt;td &gt;


Return the same number of rows as the input.&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;


Define the groups of rows on which they operate through the SQL &lt;code&gt;GROUP BY&lt;/code&gt; clause.&lt;/td&gt; 

&lt;td &gt;


Define the groups of rows on which they operate through &lt;a href=&#34;../../../en/data-analysis/sql-analytics/window-partitioning/&#34;&gt;window partition&lt;/a&gt; and &lt;a href=&#34;../../../en/data-analysis/sql-analytics/window-framing/&#34;&gt;window frame&lt;/a&gt; clauses.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;The examples below contrast the aggregate function 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/aggregate-functions/count-aggregate/#&#34;&gt;COUNT&lt;/a&gt;&lt;/code&gt; with its analytic counterpart 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/count-analytic/#&#34;&gt;COUNT&lt;/a&gt;&lt;/code&gt;. The examples use the &lt;code&gt;employees&lt;/code&gt; table as defined below:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE employees(emp_no INT, dept_no INT);
INSERT INTO employees VALUES(1, 10);
INSERT INTO employees VALUES(2, 30);
INSERT INTO employees VALUES(3, 30);
INSERT INTO employees VALUES(4, 10);
INSERT INTO employees VALUES(5, 30);
INSERT INTO employees VALUES(6, 20);
INSERT INTO employees VALUES(7, 20);
INSERT INTO employees VALUES(8, 20);
INSERT INTO employees VALUES(9, 20);
INSERT INTO employees VALUES(10, 20);
INSERT INTO employees VALUES(11, 20);
COMMIT;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When you query this table, the following result set returns:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM employees ORDER BY emp_no;
 emp_no | dept_no
--------+---------
      1 |      10
      2 |      30
      3 |      30
      4 |      10
      5 |      30
      6 |      20
      7 |      20
      8 |      20
      9 |      20
     10 |      20
     11 |      20
(11 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Below, two queries use the &lt;code&gt;COUNT&lt;/code&gt; function to count the number of employees in each department. The query on the left uses aggregate function 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/aggregate-functions/count-aggregate/#&#34;&gt;COUNT&lt;/a&gt;&lt;/code&gt;; the query on the right uses analytic function 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/count-analytic/#&#34;&gt;COUNT&lt;/a&gt;&lt;/code&gt;:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;th &gt;
Aggregate COUNT&lt;/th&gt; 

&lt;th &gt;
Analytics COUNT&lt;/th&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;







&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT dept_no, COUNT(*) AS emp_count
    FROM employees
    GROUP BY dept_no ORDER BY dept_no;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt; 

&lt;td &gt;








&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT emp_no, dept_no, COUNT(*) OVER(
     PARTITION BY dept_no
     ORDER BY emp_no) AS emp_count
     FROM employees;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;










&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; dept_no | emp_count
---------+-----------
      10 |         2
      20 |         6
      30 |         3
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt; 

&lt;td &gt;




















&lt;pre class=&#34;table-pre&#34;&gt; emp_no | dept_no | emp_count
--------+---------+-----------
      1 |      10 |         1
      4 |      10 |         2
&lt;span class=&#34;code-input&#34;&gt;------------------------------&lt;/span&gt;
      6 |      20 |         1
      7 |      20 |         2
      8 |      20 |         3
      9 |      20 |         4
     10 |      20 |         5
     11 |      20 |         6
&lt;span class=&#34;code-input&#34;&gt;------------------------------&lt;/span&gt;
      2 |      30 |         1
      3 |      30 |         2
      5 |      30 |         3
(11 rows)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;

Aggregate function
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/aggregate-functions/count-aggregate/#&#34;&gt;COUNT&lt;/a&gt;&lt;/code&gt; returns one row per department for the number of employees in that department.&lt;/td&gt; 

&lt;td &gt;

Within each &lt;code&gt;dept_no&lt;/code&gt; partition analytic function
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/count-analytic/#&#34;&gt;COUNT&lt;/a&gt;&lt;/code&gt; returns a cumulative count of employees. The count is ordered by &lt;code&gt;emp_no&lt;/code&gt;, as specified by the &lt;code&gt;ORDER BY&lt;/code&gt; clause.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;h2 id=&#34;see-also&#34;&gt;See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;../../../en/data-analysis/sql-analytics/analytic-query-examples/#&#34;&gt;Analytic query examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Window partitioning</title>
      <link>/en/data-analysis/sql-analytics/window-partitioning/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/window-partitioning/</guid>
      <description>
        
        
        &lt;p&gt;Optionally specified in a function&#39;s &lt;code&gt;OVER&lt;/code&gt; clause, a partition (&lt;code&gt;PARTITION BY&lt;/code&gt;) clause groups input rows before the function processes them. Window partitioning using PARTITION NODES or PARTITION BEST is similar to an aggregate function&#39;s &lt;code&gt;GROUP BY&lt;/code&gt; clause, except it returns exactly one result row per input row. Window partitioning using PARTITION ROW allows you to provide single-row partitions of input, allowing you to use window partitioning on 1:N transform functions. If you omit the window partition clause, the function treats all input rows as a single partition.&lt;/p&gt;
&lt;h2 id=&#34;specifying-window-partitioning&#34;&gt;Specifying window partitioning&lt;/h2&gt;
&lt;p&gt;You specify window partitioning in the function&#39;s &lt;code&gt;OVER&lt;/code&gt; clause, as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;{ PARTITION BY &lt;span class=&#34;code-variable&#34;&gt;expression&lt;/span&gt;[,...] 
  | PARTITION BEST 
  | PARTITION NODES 
  | PARTITION ROW 
  | PARTITION LEFT JOIN }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For syntax details, see &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-partition-clause/#&#34;&gt;Window partition clause&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;The examples in this topic use the &lt;code&gt;allsales&lt;/code&gt; schema defined in &lt;a href=&#34;../../../en/data-analysis/sql-analytics/invoking-analytic-functions/#&#34;&gt;Invoking analytic functions&lt;/a&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE allsales(state VARCHAR(20), name VARCHAR(20), sales INT);
INSERT INTO allsales VALUES(&amp;#39;MA&amp;#39;, &amp;#39;A&amp;#39;, 60);
INSERT INTO allsales VALUES(&amp;#39;NY&amp;#39;, &amp;#39;B&amp;#39;, 20);
INSERT INTO allsales VALUES(&amp;#39;NY&amp;#39;, &amp;#39;C&amp;#39;, 15);
INSERT INTO allsales VALUES(&amp;#39;MA&amp;#39;, &amp;#39;D&amp;#39;, 20);
INSERT INTO allsales VALUES(&amp;#39;MA&amp;#39;, &amp;#39;E&amp;#39;, 50);
INSERT INTO allsales VALUES(&amp;#39;NY&amp;#39;, &amp;#39;F&amp;#39;, 40);
INSERT INTO allsales VALUES(&amp;#39;MA&amp;#39;, &amp;#39;G&amp;#39;, 10);
COMMIT;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following query calculates the median of sales within each state. The analytic function is computed per partition and starts over again at the beginning of the next partition.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT state, name, sales, MEDIAN(sales)
      OVER (PARTITION BY state) AS median from allsales;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The results are grouped into partitions for MA (35) and NY (20) under the median column.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; state | name | sales | median
-------+------+-------+--------
 NY    | C    |    15 |     20
 NY    | B    |    20 |     20
 NY    | F    |    40 |     20
-------------------------------
 MA    | G    |    10 |     35
 MA    | D    |    20 |     35
 MA    | E    |    50 |     35
 MA    | A    |    60 |     35
(7 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following query calculates the median of total sales among states. When you use &lt;code&gt;OVER()&lt;/code&gt; with no parameters, there is one partition—the entire input:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT state, sum(sales), median(SUM(sales))
      OVER () AS median FROM allsales GROUP BY state;
 state | sum | median
-------+-----+--------
 NY    |  75 |  107.5
 MA    | 140 |  107.5
(2 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sales larger than median (evaluation order)&lt;/p&gt;
&lt;p&gt;Analytic functions are evaluated &lt;em&gt;after&lt;/em&gt; all other clauses except the query&#39;s final SQL &lt;code&gt;ORDER BY&lt;/code&gt; clause. So a query that asks for all rows with sales larger than the median returns an error because the &lt;code&gt;WHERE&lt;/code&gt; clause is applied before the analytic function and column &lt;code&gt;m&lt;/code&gt; does not yet exist:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT name, sales,  MEDIAN(sales) OVER () AS m
   FROM allsales WHERE sales &amp;gt; m;
   ERROR 2624:  Column &amp;#34;m&amp;#34; does not exist
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can work around this by placing in a subquery the predicate &lt;code&gt;WHERE sales &amp;gt; m&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM
   (SELECT name, sales, MEDIAN(sales) OVER () AS m FROM allsales) sq
   WHERE sales &amp;gt; m;
 name | sales | m
------+-------+----
 F    |    40 | 20
 E    |    50 | 20
 A    |    60 | 20
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For more examples, see &lt;a href=&#34;../../../en/data-analysis/sql-analytics/analytic-query-examples/#&#34;&gt;Analytic query examples&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Window ordering</title>
      <link>/en/data-analysis/sql-analytics/window-ordering/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/window-ordering/</guid>
      <description>
        
        
        &lt;p&gt;Window ordering specifies how to sort rows that are supplied to the function. You specify window ordering through an &lt;code&gt;ORDER BY&lt;/code&gt; clause in the function&#39;s &lt;code&gt;OVER&lt;/code&gt; clause, as shown below. If the &lt;code&gt;OVER&lt;/code&gt; clause includes a &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-partition-clause/&#34;&gt;window partition clause&lt;/a&gt;, rows are sorted within each partition. An window order clause also creates a default &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-frame-clause/&#34;&gt;window frame&lt;/a&gt; if none is explicitly specified.&lt;/p&gt;
&lt;p&gt;The window order clause only specifies order within a window result set. The query can have its own 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/statements/select/order-by-clause/#&#34;&gt;ORDER BY&lt;/a&gt;&lt;/code&gt; clause outside the &lt;code&gt;OVER&lt;/code&gt; clause. This has precedence over the window order clause and orders the final result set.&lt;/p&gt;
&lt;h2 id=&#34;specifying-window-order&#34;&gt;Specifying window order&lt;/h2&gt;
&lt;p&gt;You specify a window frame in the analytic function&#39;s &lt;code&gt;OVER&lt;/code&gt; clause, as shown below:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;ORDER BY { &lt;span class=&#34;code-variable&#34;&gt;expression&lt;/span&gt; [ ASC | DESC [ NULLS { FIRST | LAST | AUTO } ] ]
  }[,...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For syntax details, see &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-order-clause/#&#34;&gt;Window order clause&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;analytic-function-usage&#34;&gt;Analytic function usage&lt;/h2&gt;
&lt;p&gt;Analytic aggregation functions such as 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/sum-analytic/#&#34;&gt;SUM&lt;/a&gt;&lt;/code&gt; support window order clauses.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Required Usage&lt;/strong&gt;&lt;br /&gt;The following functions require a window order clause:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/rank-analytic/&#34;&gt;RANK&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/dense-rank-analytic/&#34;&gt;DENSE_RANK&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/lead-analytic/&#34;&gt;LEAD&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/lag-analytic/&#34;&gt;LAG&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/percent-rank-analytic/&#34;&gt;PERCENT_RANK&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/cume-dist-analytic/&#34;&gt;CUME_DIST&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/ntile-analytic/&#34;&gt;NTILE&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Invalid Usage&lt;/strong&gt;&lt;br /&gt;You cannot use a window order clause with the following functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/percentile-cont-analytic/&#34;&gt;PERCENTILE_CONT&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/percentile-disc-analytic/&#34;&gt;PERCENTILE_DISC&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/median-analytic/&#34;&gt;MEDIAN&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;
The examples below use the &lt;code&gt;allsales&lt;/code&gt; table schema:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE allsales(state VARCHAR(20), name VARCHAR(20), sales INT);
INSERT INTO allsales VALUES(&amp;#39;MA&amp;#39;, &amp;#39;A&amp;#39;, 60);
INSERT INTO allsales VALUES(&amp;#39;NY&amp;#39;, &amp;#39;B&amp;#39;, 20);
INSERT INTO allsales VALUES(&amp;#39;NY&amp;#39;, &amp;#39;C&amp;#39;, 15);
INSERT INTO allsales VALUES(&amp;#39;MA&amp;#39;, &amp;#39;D&amp;#39;, 20);
INSERT INTO allsales VALUES(&amp;#39;MA&amp;#39;, &amp;#39;E&amp;#39;, 50);
INSERT INTO allsales VALUES(&amp;#39;NY&amp;#39;, &amp;#39;F&amp;#39;, 40);
INSERT INTO allsales VALUES(&amp;#39;MA&amp;#39;, &amp;#39;G&amp;#39;, 10);
COMMIT;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;example-1&#34;&gt;Example 1&lt;/h3&gt;
&lt;p&gt;The following query orders sales inside each state partition:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT state, sales, name, RANK() OVER(
 PARTITION BY state &lt;span class=&#34;code-input&#34;&gt;ORDER BY sales&lt;/span&gt;) AS RANK
 FROM allsales;
 state | sales | name | RANK
-------+-------+------+----------
 MA    |    10 | G    |        1
 MA    |    20 | D    |        2
 MA    |    50 | E    |        3
 MA    |    60 | A    |        4
---------------------------------
 NY    |    15 | C    |        1
 NY    |    20 | B    |        2
 NY    |    40 | F    |        3
 (7 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;example-2&#34;&gt;Example 2&lt;/h3&gt;
&lt;p&gt;The following query&#39;s final &lt;code&gt;ORDER BY&lt;/code&gt; clause sorts results by name:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT state, sales, name, RANK() OVER(
 PARTITION BY state ORDER BY sales) AS RANK
 FROM allsales &lt;span class=&#34;code-input&#34;&gt;ORDER BY name&lt;/span&gt;;
 state | sales | name | RANK
-------+-------+------+----------
 MA    |    60 | A    |        4
 NY    |    20 | B    |        2
 NY    |    15 | C    |        1
 MA    |    20 | D    |        2
 MA    |    50 | E    |        3
 NY    |    40 | F    |        3
 MA    |    10 | G    |        1
 (7 rows)
&lt;/code&gt;&lt;/pre&gt;
      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Window framing</title>
      <link>/en/data-analysis/sql-analytics/window-framing/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/window-framing/</guid>
      <description>
        
        
        &lt;p&gt;The window frame of an analytic function comprises a set of rows relative to the row that is currently being evaluated by the function. After the analytic function processes that row and its window frame, the database advances the current row and adjusts the frame boundaries accordingly. If the OVER clause also specifies a &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-partition-clause/&#34;&gt;partition&lt;/a&gt;, the database also checks that frame boundaries do not cross partition boundaries. This process repeats until the function evaluates the last row of the last partition.&lt;/p&gt;
&lt;h2 id=&#34;specifying-a-window-frame&#34;&gt;Specifying a window frame&lt;/h2&gt;
&lt;p&gt;You specify a window frame in the analytic function&#39;s OVER clause, as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;{ ROWS | RANGE } { BETWEEN &lt;span class=&#34;code-variable&#34;&gt;start-point&lt;/span&gt; AND &lt;span class=&#34;code-variable&#34;&gt;end-point&lt;/span&gt; } | &lt;span class=&#34;code-variable&#34;&gt;start-point&lt;/span&gt;

&lt;span class=&#34;code-variable&#34;&gt;start-point&lt;/span&gt; | &lt;span class=&#34;code-variable&#34;&gt;end-point&lt;/span&gt;:

  { UNBOUNDED {PRECEDING | FOLLOWING}
    | CURRENT ROW
    | &lt;span class=&#34;code-variable&#34;&gt;constant-value&lt;/span&gt;  {PRECEDING | FOLLOWING}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;&lt;code&gt;start-point&lt;/code&gt;&lt;/em&gt; and &lt;em&gt;&lt;code&gt;end-point&lt;/code&gt;&lt;/em&gt; specify the window frame&#39;s offset from the current row. Keywords &lt;a href=&#34;../../../en/data-analysis/sql-analytics/window-framing/windows-with-physical-offset-rows/&#34;&gt;ROWS&lt;/a&gt; and &lt;a href=&#34;../../../en/data-analysis/sql-analytics/window-framing/windows-with-logical-offset-range/&#34;&gt;RANGE&lt;/a&gt; specify whether the offset is physical or logical. If you specify only a start point, the database creates a window from that point to the current row.&lt;/p&gt;
&lt;p&gt;For syntax details, see &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-frame-clause/#&#34;&gt;Window frame clause&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;requirements&#34;&gt;Requirements&lt;/h2&gt;
&lt;p&gt;In order to specify a window frame, the OVER must also specify a &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-order-clause/&#34;&gt;window order&lt;/a&gt; (ORDER BY) clause. If the OVER clause includes a window order clause but omits specifying a window frame, the function creates a default frame that extends from the first row in the current partition to the current row. This is equivalent to the following clause:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;window-aggregate-functions&#34;&gt;Window aggregate functions&lt;/h2&gt;
&lt;p&gt;Analytic functions that support window frames are called window aggregates. They return information such as moving averages and cumulative results. To use the following functions as window (analytic) aggregates, instead of basic aggregates, the OVER clause must specify a &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-order-clause/&#34;&gt;window order&lt;/a&gt; clause and, optionally, a window frame clause. If the OVER clause omits specifying a window frame, the function creates a default window frame as described earlier.&lt;/p&gt;
&lt;p&gt;The following analytic functions support window frames:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/avg-analytic/&#34;&gt;AVG&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/count-analytic/&#34;&gt;COUNT&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/max-analytic/&#34;&gt;MAX&lt;/a&gt; / &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/min-analytic/&#34;&gt;MIN&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/sum-analytic/&#34;&gt;SUM&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/stddev-analytic/&#34;&gt;STDDEV&lt;/a&gt; / &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/stddev-analytic/&#34;&gt;STDDEV_POP&lt;/a&gt; / &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/stddev-analytic/&#34;&gt;STDDEV_SAMP&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/variance-analytic/&#34;&gt;VARIANCE&lt;/a&gt; / &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/var-pop-analytic/&#34;&gt;VAR_POP&lt;/a&gt; / &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/var-samp-analytic/&#34;&gt;VAR_SAMP&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

Functions &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/first-value-analytic/&#34;&gt;FIRST_VALUE&lt;/a&gt; and &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/last-value-analytic/&#34;&gt;LAST_VALUE&lt;/a&gt; also support window frames, but they are only analytic functions with no aggregate counterpart. &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/exponential-moving-average-analytic/&#34;&gt;EXPONENTIAL_MOVING_AVERAGE&lt;/a&gt;, &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/lag-analytic/&#34;&gt;LAG&lt;/a&gt;, and &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/lead-analytic/&#34;&gt;LEAD&lt;/a&gt; analytic functions do not support window frames.

&lt;/div&gt;
&lt;p&gt;A window aggregate with an empty OVER clause creates no window frame. The function is used as a reporting function, where all input is treated as a single partition.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Named windows</title>
      <link>/en/data-analysis/sql-analytics/named-windows/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/named-windows/</guid>
      <description>
        
        
        &lt;p&gt;An analytic function&#39;s &lt;code&gt;OVER&lt;/code&gt; clause can reference a named window, which encapsulates one or more window clauses: a window partition (&lt;code&gt;PARTITION BY&lt;/code&gt;) clause and (optionally) a window order (&lt;code&gt;ORDER BY&lt;/code&gt;) clause. Named windows can be useful when you write queries that invoke multiple analytic functions with similar &lt;code&gt;OVER&lt;/code&gt; clause syntax—for example, they use the same partition clauses.&lt;/p&gt;
&lt;p&gt;A query names a window as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;WINDOW &lt;span class=&#34;code-variable&#34;&gt;window-name&lt;/span&gt; AS ( &lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-partition-clause/#&#34;&gt;window-partition-clause&lt;/a&gt;&lt;/span&gt; [&lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-order-clause/#&#34;&gt;window-order-clause&lt;/a&gt;&lt;/span&gt;] );
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The same query can name and reference multiple windows. All window names must be unique within the same query.&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;The following query invokes two analytic functions, 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/rank-analytic/#&#34;&gt;RANK&lt;/a&gt;&lt;/code&gt; and 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/dense-rank-analytic/#&#34;&gt;DENSE_RANK&lt;/a&gt;&lt;/code&gt;. Because the two functions use the same partition and order clauses, the query names a window &lt;code&gt;w&lt;/code&gt; that specifies both clauses. The two functions reference this window as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT employee_region region, employee_key, annual_salary,
     RANK() OVER w Rank,
     DENSE_RANK() OVER w &amp;#34;Dense Rank&amp;#34;
     FROM employee_dimension WINDOW w AS (PARTITION BY employee_region ORDER BY annual_salary);
              region              | employee_key | annual_salary | Rank | Dense Rank
----------------------------------+--------------+---------------+------+------------
 West                             |         5248 |          1200 |    1 |          1
 West                             |         6880 |          1204 |    2 |          2
 West                             |         5700 |          1214 |    3 |          3
 West                             |         9857 |          1218 |    4 |          4
 West                             |         6014 |          1218 |    4 |          4
 West                             |         9221 |          1220 |    6 |          5
 West                             |         7646 |          1222 |    7 |          6
 West                             |         6621 |          1222 |    7 |          6
 West                             |         6488 |          1224 |    9 |          7
 West                             |         7659 |          1226 |   10 |          8
 West                             |         7432 |          1226 |   10 |          8
 West                             |         9905 |          1226 |   10 |          8
 West                             |         9021 |          1228 |   13 |          9
 West                             |         7855 |          1228 |   13 |          9
 West                             |         7119 |          1230 |   15 |         10
 ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the named window omits an order clause, the query&#39;s &lt;code&gt;OVER&lt;/code&gt; clauses can specify their own order clauses. For example, you can modify the previous query so each function uses a different order clause. The named window is defined so it includes only a partition clause:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT employee_region region, employee_key, annual_salary,
    RANK() OVER (&lt;span class=&#34;code-input&#34;&gt;w ORDER BY annual_salary DESC&lt;/span&gt;) Rank,
    DENSE_RANK() OVER (w ORDER BY annual_salary ASC) &amp;#34;Dense Rank&amp;#34;
    FROM employee_dimension WINDOW w AS (PARTITION BY employee_region);
              region              | employee_key | annual_salary | Rank | Dense Rank
----------------------------------+--------------+---------------+------+------------
 West                             |         5248 |          1200 | 2795 |          1
 West                             |         6880 |          1204 | 2794 |          2
 West                             |         5700 |          1214 | 2793 |          3
 West                             |         6014 |          1218 | 2791 |          4
 West                             |         9857 |          1218 | 2791 |          4
 West                             |         9221 |          1220 | 2790 |          5
 West                             |         6621 |          1222 | 2788 |          6
 West                             |         7646 |          1222 | 2788 |          6
 West                             |         6488 |          1224 | 2787 |          7
 West                             |         7432 |          1226 | 2784 |          8
 West                             |         9905 |          1226 | 2784 |          8
 West                             |         7659 |          1226 | 2784 |          8
 West                             |         7855 |          1228 | 2782 |          9
 West                             |         9021 |          1228 | 2782 |          9
 West                             |         7119 |          1230 | 2781 |         10
 ...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similarly, an &lt;code&gt;OVER&lt;/code&gt; clause specifies a named window can also specify a &lt;a href=&#34;../../../en/sql-reference/language-elements/window-clauses/window-frame-clause/&#34;&gt;window frame clause&lt;/a&gt;, provided the named window includes an order clause. This can be useful inasmuch as you cannot define a named windows to include a window frame clause.&lt;/p&gt;
&lt;p&gt;For example, the following query defines a window that encapsulates partitioning and order clauses. The &lt;code&gt;OVER&lt;/code&gt; clause invokes this window and also includes a window frame clause:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT deptno, sal, empno,  COUNT(*) OVER (&lt;span class=&#34;code-input&#34;&gt;w ROWS BETWEEN 2 PRECEDING AND CURRENT ROW&lt;/span&gt;) AS count
 FROM emp WINDOW w AS (PARTITION BY deptno ORDER BY sal);
 deptno | sal | empno | count
--------+-----+-------+-------
     10 | 101 |     1 |     1
     10 | 104 |     4 |     2
     20 | 100 |    11 |     1
     20 | 109 |     8 |     2
     20 | 109 |     6 |     3
     20 | 109 |     7 |     3
     20 | 110 |    10 |     3
     20 | 110 |     9 |     3
     30 | 102 |     2 |     1
     30 | 103 |     3 |     2
     30 | 105 |     5 |     3
(11 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;recursive-window-references&#34;&gt;Recursive window references&lt;/h2&gt;
&lt;p&gt;A &lt;code&gt;WINDOW&lt;/code&gt; clause can reference another window that is already named. For example, because named window &lt;code&gt;w1&lt;/code&gt; is defined before &lt;code&gt;w2&lt;/code&gt;, the &lt;code&gt;WINDOW&lt;/code&gt; clause that defines &lt;code&gt;w2&lt;/code&gt; can reference &lt;code&gt;w1&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT RANK() OVER(w1 ORDER BY sal DESC), RANK() OVER w2
   FROM EMP WINDOW w1 AS (PARTITION BY deptno), w2 AS (w1 ORDER BY sal);
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;restrictions&#34;&gt;Restrictions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;An &lt;code&gt;OVER&lt;/code&gt; clause can reference only one named window.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Each &lt;code&gt;WINDOW&lt;/code&gt; clause within the same query must have a unique name.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Analytic query examples</title>
      <link>/en/data-analysis/sql-analytics/analytic-query-examples/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/analytic-query-examples/</guid>
      <description>
        
        
        &lt;p&gt;The topics in this section show how to use analytic queries for calculations.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Event-based windows</title>
      <link>/en/data-analysis/sql-analytics/event-based-windows/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/event-based-windows/</guid>
      <description>
        
        
        &lt;p&gt;
Event-based windows let you break time series data into windows that border on significant events within the data. This is especially relevant in financial data where analysis often focuses on specific events as triggers to other activity.&lt;/p&gt;
&lt;p&gt;OpenText™ Analytics Database provides two event-based window functions that are not part of the SQL-99 standard:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/conditional-change-event-analytic/#&#34;&gt;CONDITIONAL_CHANGE_EVENT&lt;/a&gt;&lt;/code&gt; assigns an event window number to each row, starting from 0, and increments by 1 when the result of evaluating the argument expression on the current row differs from that on the previous row. This function is similar to the analytic function 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/row-number-analytic/#&#34;&gt;ROW_NUMBER&lt;/a&gt;&lt;/code&gt;, which assigns a unique number, sequentially, starting from 1, to each row within a partition.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/conditional-true-event-analytic/#&#34;&gt;CONDITIONAL_TRUE_EVENT&lt;/a&gt;&lt;/code&gt; assigns an event window number to each row, starting from 0, and increments the number by 1 when the result of the boolean argument expression evaluates true.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both functions are described in greater detail below.

&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

&lt;code&gt;CONDITIONAL_CHANGE_EVENT&lt;/code&gt; and &lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; do not support &lt;a href=&#34;../../../en/data-analysis/sql-analytics/window-framing/&#34;&gt;window framing&lt;/a&gt;.

&lt;/div&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example schema&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The examples on this page use the following schema:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE TickStore3 (ts TIMESTAMP, symbol VARCHAR(8), bid FLOAT);
CREATE PROJECTION TickStore3_p (ts, symbol, bid) AS SELECT * FROM TickStore3 ORDER BY ts, symbol, bid UNSEGMENTED ALL NODES;
INSERT INTO TickStore3 VALUES (&amp;#39;2009-01-01 03:00:00&amp;#39;, &amp;#39;XYZ&amp;#39;, 10.0);
INSERT INTO TickStore3 VALUES (&amp;#39;2009-01-01 03:00:03&amp;#39;, &amp;#39;XYZ&amp;#39;, 11.0);
INSERT INTO TickStore3 VALUES (&amp;#39;2009-01-01 03:00:06&amp;#39;, &amp;#39;XYZ&amp;#39;, 10.5);
INSERT INTO TickStore3 VALUES (&amp;#39;2009-01-01 03:00:09&amp;#39;, &amp;#39;XYZ&amp;#39;, 11.0);
COMMIT;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;using-conditional_change_event&#34;&gt;Using CONDITIONAL_CHANGE_EVENT&lt;/h2&gt;
&lt;p&gt;The analytical function &lt;code&gt;CONDITIONAL_CHANGE_EVENT&lt;/code&gt; returns a sequence of integers indicating event window numbers, starting from 0. The function increments the event window number when the result of evaluating the function expression on the current row differs from the previous value.&lt;/p&gt;
&lt;p&gt;In the following example, the first query returns all records from the TickStore3 table. The second query uses the CONDITIONAL_CHANGE_EVENT function on the bid column. Since each bid row value is different from the previous value, the function increments the window ID from 0 to 3:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;td &gt;


&lt;code&gt;SELECT ts, symbol, bidFROM Tickstore3 ORDER BY ts;&lt;/code&gt;&lt;/td&gt; 

&lt;td &gt;
&lt;/td&gt; 

&lt;td &gt;






&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT CONDITIONAL_CHANGE_EVENT(bid)
  OVER(ORDER BY ts) FROM Tickstore3;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;











&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;         ts          | symbol | bid
---------------------+--------+------
 2009-01-01 03:00:00 | XYZ    |   10
 2009-01-01 03:00:03 | XYZ    |   11
 2009-01-01 03:00:06 | XYZ    | 10.5
 2009-01-01 03:00:09 | XYZ    |   11
(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt; 

&lt;td &gt;


&lt;strong&gt;&lt;code&gt;==&amp;amp;gt;&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt; 

&lt;td &gt;











&lt;pre class=&#34;table-pre&#34;&gt;         ts          | symbol | bid  | cce
---------------------+--------+------+-----
 2009-01-01 03:00:00 | XYZ    |   10 | 0
 2009-01-01 03:00:03 | XYZ    |   11 | 1
 2009-01-01 03:00:06 | XYZ    | 10.5 | 2
 2009-01-01 03:00:09 | XYZ    |   11 | 3
(4 rows)
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;The following figure is a graphical illustration of the change in the bid price. Each value is different from its previous one, so the window ID increments for each time slice:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../../images/cce.png&#34; alt=&#34;CONDITINAL CHANG EVENT&#34;&gt;&lt;/p&gt;
&lt;p&gt;So the window ID starts at 0 and increments at every change in from the previous value.&lt;/p&gt;
&lt;p&gt;In this example, the bid price changes from $10 to $11 in the second row, but then stays the same. &lt;code&gt;CONDITIONAL_CHANGE_EVENT&lt;/code&gt; increments the event window ID in row 2, but not subsequently:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;td &gt;


&lt;code&gt;SELECT ts, symbol, bidFROM Tickstore3 ORDER BY ts;&lt;/code&gt;&lt;/td&gt; 

&lt;td &gt;
&lt;/td&gt; 

&lt;td &gt;






&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT CONDITIONAL_CHANGE_EVENT(bid)
  OVER(ORDER BY ts) FROM Tickstore3;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;










&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;         ts          | symbol | bid
---------------------+--------+------
 2009-01-01 03:00:00 | XYZ    |   10
 2009-01-01 03:00:03 | XYZ    |   11
 2009-01-01 03:00:06 | XYZ    |   11
 2009-01-01 03:00:09 | XYZ    |   11
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt; 

&lt;td &gt;


&lt;code&gt;==&amp;gt;&lt;/code&gt;&lt;/td&gt; 

&lt;td &gt;










&lt;pre class=&#34;table-pre&#34;&gt;         ts          | symbol | bid  | cce
---------------------+--------+------+-----
 2009-01-01 03:00:00 | XYZ    |   10 | 0
 2009-01-01 03:00:03 | XYZ    |   11 | 1
 2009-01-01 03:00:06 | XYZ    |   11 | 1
 2009-01-01 03:00:09 | XYZ    |   11 | 1
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;The following figure is a graphical illustration of the change in the bid price at 3:00:03 only. The price stays the same at 3:00:06 and 3:00:09, so the window ID remains at 1 for each time slice after the change:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;![CCE 2](/images/cce2.png)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;using-conditional_true_event&#34;&gt;Using CONDITIONAL_TRUE_EVENT&lt;/h2&gt;
&lt;p&gt;Like &lt;code&gt;CONDITIONAL_CHANGE_EVENT&lt;/code&gt;, the analytic function &lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; also returns a sequence of integers indicating event window numbers, starting from 0. The two functions differ as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; increments the window ID each time its expression evaluates to true.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;CONDITIONAL_CHANGE_EVENT&lt;/code&gt; increments on a comparison expression with the previous value.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the following example, the first query returns all records from the TickStore3 table. The second query uses &lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; to test whether the current bid is greater than a given value (10.6). Each time the expression tests true, the function increments the window ID. The first time the function increments the window ID is on row 2, when the value is 11. The expression tests false for the next row (value is not greater than 10.6), so the function does not increment the event window ID. In the final row, the expression is true for the given condition, and the function increments the window:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;td &gt;


&lt;code&gt;SELECT ts, symbol, bidFROM Tickstore3 ORDER BY ts;&lt;/code&gt;&lt;/td&gt; 

&lt;td &gt;
&lt;/td&gt; 

&lt;td &gt;






&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT CONDITIONAL_TRUE_EVENT(bid &amp;gt; 10.6)
  OVER(ORDER BY ts) FROM Tickstore3;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;










&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;         ts          | symbol | bid
---------------------+--------+------
 2009-01-01 03:00:00 | XYZ    |   10
 2009-01-01 03:00:03 | XYZ    |   11
 2009-01-01 03:00:06 | XYZ    | 10.5
 2009-01-01 03:00:09 | XYZ    |   11
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt; 

&lt;td &gt;


&lt;code&gt;==&amp;gt;&lt;/code&gt;&lt;/td&gt; 

&lt;td &gt;









&lt;pre class=&#34;table-pre&#34;&gt;         ts          | symbol | bid  | cte---------------------+--------+------+-----
 2009-01-01 03:00:00 | XYZ    |   10 | 0
 2009-01-01 03:00:03 | XYZ    |   11 | 1
 2009-01-01 03:00:06 | XYZ    | 10.5 | 1
 2009-01-01 03:00:09 | XYZ    |   11 | 2
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;The following figure is a graphical illustration that shows the bid values and window ID changes. Because the bid value is greater than $10.6 on only the second and fourth time slices (3:00:03 and 3:00:09), the window ID returns &amp;lt;0,&lt;strong&gt;1&lt;/strong&gt;,1,&lt;strong&gt;2&lt;/strong&gt;&amp;gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../../images/cte.png&#34; alt=&#34;CTE&#34;&gt;&lt;/p&gt;
&lt;p&gt;In the following example, the first query returns all records from the TickStore3 table, ordered by the tickstore values (ts). The second query uses &lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; to increment the window ID each time the bid value is greater than 10.6. The first time the function increments the event window ID is on row 2, where the value is 11. The window ID then increments each time after that, because the expression (bid &amp;gt; 10.6) tests true for each time slice:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;td &gt;


&lt;code&gt;SELECT ts, symbol, bidFROM Tickstore3 ORDER BY ts;&lt;/code&gt;&lt;/td&gt; 

&lt;td &gt;
&lt;/td&gt; 

&lt;td &gt;






&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT CONDITIONAL_TRUE_EVENT(bid &amp;gt; 10.6)
  OVER(ORDER BY ts)‏ FROM Tickstore3;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;










&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;         ts          | symbol | bid
---------------------+--------+------
 2009-01-01 03:00:00 | XYZ    |   10
 2009-01-01 03:00:03 | XYZ    |   11
 2009-01-01 03:00:06 | XYZ    |   11
 2009-01-01 03:00:09 | XYZ    |   11
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt; 

&lt;td &gt;


&lt;code&gt;==&amp;gt;&lt;/code&gt;&lt;/td&gt; 

&lt;td &gt;










&lt;pre class=&#34;table-pre&#34;&gt;         ts          | symbol | bid  | cte
---------------------+--------+------+-----
 2009-01-01 03:00:00 | XYZ    |   10 | 0
 2009-01-01 03:00:03 | XYZ    |   11 | 1
 2009-01-01 03:00:06 | XYZ    |   11 | 2
 2009-01-01 03:00:09 | XYZ    |   11 | 3
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;The following figure is a graphical illustration that shows the bid values and window ID changes. The bid value is greater than 10.6 on the second time slice (3:00:03) and remains for the remaining two time slices. The function increments the event window ID each time because the expression tests true:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../../images/cte2.png&#34; alt=&#34;cte2&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;advanced-use-of-event-based-windows&#34;&gt;Advanced use of event-based windows&lt;/h2&gt;
&lt;p&gt;In event-based window functions, the condition expression accesses values from the current row only. To access a previous value, you can use a more powerful event-based window that allows the window event condition to include previous data points. For example, analytic function &lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/lag-analytic/&#34;&gt;LAG&lt;/a&gt;(x, n) retrieves the value of column x in the &lt;em&gt;n&lt;/em&gt;th to last input record. In this case, &lt;code&gt;LAG&lt;/code&gt; shares the &lt;code&gt;OVER&lt;/code&gt; specifications of the &lt;code&gt;CONDITIONAL_CHANGE_EVENT&lt;/code&gt; or &lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; function expression.&lt;/p&gt;
&lt;p&gt;In the following example, the first query returns all records from the TickStore3 table. The second query uses &lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; with the &lt;code&gt;LAG&lt;/code&gt; function in its boolean expression. In this case, &lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; increments the event window ID each time the bid value on the current row is less than the previous value. The first time &lt;code&gt;CONDITIONAL_TRUE_EVENT&lt;/code&gt; increments the window ID starts on the third time slice, when the expression tests true. The current value (10.5) is less than the previous value. The window ID is not incremented in the last row because the final value is greater than the previous row:

&lt;table class=&#34;table table-bordered&#34; &gt;



&lt;tr&gt; 

&lt;td &gt;


&lt;code&gt;SELECT ts, symbol, bidFROM Tickstore3 ORDER BY ts;&lt;/code&gt;&lt;/td&gt; 

&lt;td &gt;






&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT CONDITIONAL_TRUE_EVENT(bid &amp;lt; LAG(bid))
  OVER(ORDER BY ts) FROM Tickstore;
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;

&lt;tr&gt; 

&lt;td &gt;










&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;         ts          | symbol | bid
---------------------+--------+------
 2009-01-01 03:00:00 | XYZ    |   10
 2009-01-01 03:00:03 | XYZ    |   11
 2009-01-01 03:00:06 | XYZ    | 10.5
 2009-01-01 03:00:09 | XYZ    |   11
&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt; 

&lt;td &gt;










&lt;pre class=&#34;table-pre&#34;&gt;         ts          | symbol | bid  | cte
---------------------+--------+------+-----
 2009-01-01 03:00:00 | XYZ    |   10 | 0
 2009-01-01 03:00:03 | XYZ    |   11 | 0
 2009-01-01 03:00:06 | XYZ    | 10.5 | 1
 2009-01-01 03:00:09 | XYZ    |   11 | 1
&lt;/pre&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;The following figure illustrates the second query above. When the bid price is less than the previous value, the window ID gets incremented, which occurs only in the third time slice (3:00:06):&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;../../../images/cte3.png&#34; alt=&#34;cte3&#34;&gt;
&lt;/p&gt;
&lt;h2 id=&#34;see-also&#34;&gt;See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/data-analysis/sql-analytics/sessionization-with-event-based-windows/#&#34;&gt;Sessionization with event-based windows&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/data-analysis/time-series-analytics/#&#34;&gt;Time series analytics&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Sessionization with event-based windows</title>
      <link>/en/data-analysis/sql-analytics/sessionization-with-event-based-windows/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/sql-analytics/sessionization-with-event-based-windows/</guid>
      <description>
        
        
        &lt;p&gt;Sessionization, a special case of event-based windows, is a feature often used to analyze click streams, such as identifying web browsing sessions from recorded web clicks.&lt;/p&gt;
&lt;p&gt;In OpenText™ Analytics Database, given an input clickstream table, where each row records a Web page click made by a particular user (or IP address), the sessionization computation attempts to identify Web browsing sessions from the recorded clicks by grouping the clicks from each user based on the time-intervals between the clicks. If two clicks from the same user are made too far apart in time, as defined by a time-out threshold, the clicks are treated as though they are from two different browsing sessions.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example Schema&lt;/strong&gt;

The examples in this topic use the following WebClicks schema to represent a simple clickstream table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;CREATE TABLE WebClicks(userId INT, timestamp TIMESTAMP);
INSERT INTO WebClicks VALUES (1, &amp;#39;2009-12-08 3:00:00 pm&amp;#39;);
INSERT INTO WebClicks VALUES (1, &amp;#39;2009-12-08 3:00:25 pm&amp;#39;);
INSERT INTO WebClicks VALUES (1, &amp;#39;2009-12-08 3:00:45 pm&amp;#39;);
INSERT INTO WebClicks VALUES (1, &amp;#39;2009-12-08 3:01:45 pm&amp;#39;);
INSERT INTO WebClicks VALUES (2, &amp;#39;2009-12-08 3:02:45 pm&amp;#39;);
INSERT INTO WebClicks VALUES (2, &amp;#39;2009-12-08 3:02:55 pm&amp;#39;);
INSERT INTO WebClicks VALUES (2, &amp;#39;2009-12-08 3:03:55 pm&amp;#39;);
COMMIT;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The input table &lt;code&gt;WebClicks&lt;/code&gt; contains the following rows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM WebClicks;
 userId |      timestamp
--------+---------------------
      1 | 2009-12-08 15:00:00
      1 | 2009-12-08 15:00:25
      1 | 2009-12-08 15:00:45
      1 | 2009-12-08 15:01:45
      2 | 2009-12-08 15:02:45
      2 | 2009-12-08 15:02:55
      2 | 2009-12-08 15:03:55
(7 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the following query, sessionization performs computation on the SELECT list columns, showing the difference between the current and previous timestamp value using &lt;code&gt;LAG()&lt;/code&gt;. It evaluates to true and increments the window ID when the difference is greater than 30 seconds.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT userId, timestamp,
     CONDITIONAL_TRUE_EVENT(timestamp - LAG(timestamp) &amp;gt; &amp;#39;30 seconds&amp;#39;)
     OVER(PARTITION BY userId ORDER BY timestamp) AS session FROM WebClicks;
 userId |      timestamp      | session
--------+---------------------+---------
      1 | 2009-12-08 15:00:00 |       0
      1 | 2009-12-08 15:00:25 |       0
      1 | 2009-12-08 15:00:45 |       0
      1 | 2009-12-08 15:01:45 |       1
      2 | 2009-12-08 15:02:45 |       0
      2 | 2009-12-08 15:02:55 |       0
      2 | 2009-12-08 15:03:55 |       1
(7 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the output, the session column contains the window ID from the CONDITIONAL_TRUE_EVENT function. The window ID evaluates to true on row 4 (timestamp 15:01:45), and the ID that follows row 4 is zero because it is the start of a new partition (for user ID 2), and that row does not evaluate to true until the last line in the output.&lt;/p&gt;
&lt;p&gt;You might want to give users different time-out thresholds. For example, one user might have a slower network connection or be multi-tasking, while another user might have a faster connection and be focused on a single Web site, doing a single task.&lt;/p&gt;
&lt;p&gt;To compute an adaptive time-out threshold based on the last 2 clicks, use CONDITIONAL_TRUE_EVENT with LAG to return the average time between the last 2 clicks with a grace period of 3 seconds:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT userId, timestamp, CONDITIONAL_TRUE_EVENT(timestamp - LAG(timestamp) &amp;gt;
(LAG(timestamp, 1) - LAG(timestamp, 3)) / 2 + &amp;#39;3 seconds&amp;#39;)
OVER(PARTITION BY userId ORDER BY timestamp) AS session
FROM WebClicks;
 userId |      timestamp      | session
--------+---------------------+---------
      2 | 2009-12-08 15:02:45 |       0
      2 | 2009-12-08 15:02:55 |       0
      2 | 2009-12-08 15:03:55 |       0
      1 | 2009-12-08 15:00:00 |       0
      1 | 2009-12-08 15:00:25 |       0
      1 | 2009-12-08 15:00:45 |       0
      1 | 2009-12-08 15:01:45 |       1
(7 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;
&lt;div class=&#34;alert admonition note&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Note&lt;/h4&gt;

You cannot define a moving window in time series data. For example, if the query is evaluating the first row and there’s no data, it will be the current row. If you have a lag of 2, no results are returned until the third row.

&lt;/div&gt;
&lt;/p&gt;
&lt;h2 id=&#34;see-also&#34;&gt;See also&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/data-analysis/sql-analytics/event-based-windows/#&#34;&gt;Event-based windows&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href=&#34;../../../en/sql-reference/functions/analytic-functions/conditional-true-event-analytic/#&#34;&gt;CONDITIONAL_TRUE_EVENT [analytic]&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
  </channel>
</rss>
