<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OpenText Analytics Database 26.2.x – Joins</title>
    <link>/en/data-analysis/queries/joins/</link>
    <description>Recent content in Joins on OpenText Analytics Database 26.2.x</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/en/data-analysis/queries/joins/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Data-Analysis: Join syntax</title>
      <link>/en/data-analysis/queries/joins/join-syntax/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/joins/join-syntax/</guid>
      <description>
        
        
        &lt;p&gt;OpenText™ Analytics Database supports the ANSI SQL-92 standard for joining tables, as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../../en/sql-reference/statements/select/from-clause/table-reference/#&#34;&gt;table-reference&lt;/a&gt;&lt;/span&gt; [&lt;span class=&#34;code-variable&#34;&gt;join-type&lt;/span&gt;] JOIN &lt;span class=&#34;code-variable&#34;&gt;table-reference&lt;/span&gt; [ ON &lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../../en/sql-reference/language-elements/predicates/interpolate/join-predicate/#&#34;&gt;join-predicate&lt;/a&gt;&lt;/span&gt; ]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;where &lt;em&gt;&lt;code&gt;join-type&lt;/code&gt;&lt;/em&gt; can be one of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;
&lt;code&gt;&lt;a href=&#34;../../../../en/data-analysis/queries/joins/inner-joins/#&#34;&gt;INNER&lt;/a&gt;&lt;/code&gt; (default)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;

&lt;code&gt;&lt;a href=&#34;../../../../en/data-analysis/queries/joins/outer-joins/#LeftOuterJoin&#34;&gt;LEFT [ OUTER ]&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;

&lt;code&gt;&lt;a href=&#34;../../../../en/data-analysis/queries/joins/outer-joins/#RightOuterJoin&#34;&gt;RIGHT [ OUTER ]&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;

&lt;code&gt;&lt;a href=&#34;../../../../en/data-analysis/queries/joins/outer-joins/#FullOuterJoin&#34;&gt;FULL [ OUTER ]&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;

&lt;code&gt;&lt;a href=&#34;../../../../en/data-analysis/queries/joins/inner-joins/natural-joins/#&#34;&gt;NATURAL&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;

&lt;code&gt;&lt;a href=&#34;../../../../en/data-analysis/queries/joins/inner-joins/cross-joins/#&#34;&gt;CROSS&lt;/a&gt;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM T1 INNER JOIN T2 ON T1.id = T2.id;
&lt;/code&gt;&lt;/pre&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;

The &lt;code&gt;ON &lt;/code&gt;&lt;em&gt;&lt;code&gt;join-predicate&lt;/code&gt;&lt;/em&gt; clause is invalid for &lt;span class=&#34;sql&#34;&gt;NATURAL&lt;/span&gt; and &lt;span class=&#34;sql&#34;&gt;CROSS&lt;/span&gt; joins, required for all other join types.

&lt;/div&gt;
&lt;p&gt;&lt;a name=&#34;AlternativeJoinSyntax&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;alternative-syntax-options&#34;&gt;Alternative syntax options&lt;/h2&gt;
&lt;p&gt;OpenText™ Analytics Database also supports two older join syntax conventions:&lt;/p&gt;
&lt;h3 id=&#34;join-specified-by-where-clause-join-predicate&#34;&gt;Join specified by WHERE clause join predicate&lt;/h3&gt;
&lt;p&gt;&lt;span class=&#34;sql&#34;&gt;INNER JOIN&lt;/span&gt; is equivalent to a query that specifies its join predicate in a &lt;span class=&#34;sql&#34;&gt;WHERE&lt;/span&gt; clause. For example, this example and the previous one return equivalent results. They both specify an inner join between tables &lt;code&gt;T1&lt;/code&gt; and &lt;code&gt;T2&lt;/code&gt; on columns &lt;code&gt;T1.id&lt;/code&gt; and &lt;code&gt;T2.id&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM T1, T2 WHERE T1.id = T2.id;
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;join-using-clause&#34;&gt;JOIN USING clause&lt;/h3&gt;
&lt;p&gt;You can join two tables on identically named columns with a &lt;span class=&#34;sql&#34;&gt;JOIN USING&lt;/span&gt; clause. For example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM T1 JOIN T2 USING(id);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By default, a join that is specified by &lt;span class=&#34;sql&#34;&gt;JOIN USING&lt;/span&gt; is always an inner join.

&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;

JOIN USING joins the two tables by combining the two join columns into one. Therefore, the two join column data types must be the same or compatible—for example, FLOAT and INTEGER—regardless of the actual data in the joined columns.

&lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&#34;benefits-of-sql-92-join-syntax&#34;&gt;Benefits of SQL-92 join syntax&lt;/h2&gt;
&lt;p&gt;OpenText recommends that you use SQL-92 join syntax for several reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;SQL-92 outer join syntax is portable across databases; the older syntax was not consistent between databases.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SQL-92 syntax provides greater control over whether predicates are evaluated during or after outer joins. This was also not consistent between databases when using the older syntax.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SQL-92 syntax eliminates ambiguity in the order of evaluating the joins, in cases where more than two tables are joined with outer joins.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Join conditions vs. filter conditions</title>
      <link>/en/data-analysis/queries/joins/join-conditions-vs-filter-conditions/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/joins/join-conditions-vs-filter-conditions/</guid>
      <description>
        
        
        &lt;p&gt;If you do not use the SQL-92 syntax, join conditions (predicates that are evaluated during the join) are difficult to distinguish from filter conditions (predicates that are evaluated after the join), and in some cases cannot be expressed at all. With SQL-92, join conditions and filter conditions are separated into two different clauses, the &lt;code&gt;ON&lt;/code&gt; clause and the &lt;code&gt;WHERE&lt;/code&gt; clause, respectively, making queries easier to understand.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The ON clause&lt;/strong&gt; contains relational operators (for example, &amp;lt;, &amp;lt;=, &amp;gt;, &amp;gt;=, &amp;lt;&amp;gt;, =, &amp;lt;=&amp;gt;) or other predicates that specify which records from the left and right input relations to combine, such as by matching foreign keys to primary keys. &lt;code&gt;ON&lt;/code&gt; can be used with inner, left outer, right outer, and full outer joins. Cross joins and union joins do not use an &lt;code&gt;ON&lt;/code&gt; clause.&lt;/p&gt;
&lt;p&gt;Inner joins return all pairings of rows from the left and right relations for which the &lt;code&gt;ON&lt;/code&gt; clause evaluates to TRUE. In a left join, all rows from the left relation in the join are present in the result; any row of the left relation that does not match any rows in the right relation is still present in the result but with nulls in any columns taken from the right relation. Similarly, a right join preserves all rows from the right relation, and a full join retains all rows from both relations.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;The WHERE clause&lt;/strong&gt; is evaluated after the join is performed. It filters records returned by the &lt;code&gt;FROM&lt;/code&gt; clause, eliminating any records that do not satisfy the &lt;code&gt;WHERE&lt;/code&gt; clause condition.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The database automatically converts outer joins to inner joins in cases where it is correct to do so, allowing the optimizer to choose among a wider set of query plans and leading to better performance.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Inner joins</title>
      <link>/en/data-analysis/queries/joins/inner-joins/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/joins/inner-joins/</guid>
      <description>
        
        
        &lt;p&gt;An inner join combines records from two tables based on a join predicate and requires that each record in the first table has a matching record in the second table. Thus, inner joins return only records from both joined tables that satisfy the join condition. Records that contain no matches are excluded from the result set.&lt;/p&gt;
&lt;p&gt;Inner joins take the following form:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT &lt;span class=&#34;code-variable&#34;&gt;column-list&lt;/span&gt; FROM &lt;span class=&#34;code-variable&#34;&gt;left-join-table&lt;/span&gt;
  [INNER] JOIN &lt;span class=&#34;code-variable&#34;&gt;right-join-table&lt;/span&gt; ON &lt;span class=&#34;code-variable&#34;&gt;&lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../../en/sql-reference/language-elements/predicates/interpolate/join-predicate/#&#34;&gt;join-predicate&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you omit the &lt;code&gt;INNER&lt;/code&gt; keyword, the database assumes an inner join. Inner joins are commutative and associative. You can specify tables in any order without changing the results.&lt;/p&gt;
&lt;h2 id=&#34;example&#34;&gt;Example&lt;/h2&gt;
&lt;p&gt;The following example specifies an inner join between tables &lt;code&gt;store.store_dimension&lt;/code&gt; and &lt;code&gt;public.employee_dimension&lt;/code&gt; whose records have matching values in columns &lt;code&gt;store_region&lt;/code&gt; and &lt;code&gt;employee_region&lt;/code&gt;, respectively:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT s.store_region, SUM(e.vacation_days) TotalVacationDays
   FROM public.employee_dimension e
   JOIN store.store_dimension s ON s.store_region=e.employee_region
   GROUP BY s.store_region ORDER BY TotalVacationDays;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This join can also be expressed as follows:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT s.store_region, SUM(e.vacation_days) TotalVacationDays
    FROM public.employee_dimension e, store.store_dimension s
    WHERE s.store_region=e.employee_region
    GROUP BY s.store_region ORDER BY TotalVacationDays;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Both queries return the same result set:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; store_region | TotalVacationDays
--------------+-------------------
 NorthWest    |             23280
 SouthWest    |            367250
 MidWest      |            925938
 South        |           1280468
 East         |           1952854
 West         |           2849976
(6 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the join&#39;s inner table &lt;code&gt;store.store_dimension&lt;/code&gt; has any rows with &lt;code&gt;store_region&lt;/code&gt; values that do not match &lt;code&gt;employee_region&lt;/code&gt; values in table &lt;code&gt;public.employee_dimension&lt;/code&gt;, those rows are excluded from the result set. To include that row, you can specify an &lt;a href=&#34;../../../../en/data-analysis/queries/joins/outer-joins/&#34;&gt;outer join&lt;/a&gt;.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Outer joins</title>
      <link>/en/data-analysis/queries/joins/outer-joins/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/joins/outer-joins/</guid>
      <description>
        
        
        &lt;p&gt;Outer joins extend the functionality of inner joins by letting you preserve rows of one or both tables that do not have matching rows in the non-preserved table. Outer joins take the following form:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT &lt;span class=&#34;code-variable&#34;&gt;column-list&lt;/span&gt; FROM &lt;span class=&#34;code-variable&#34;&gt;left-join-table&lt;/span&gt;
[ LEFT | RIGHT | FULL ] OUTER JOIN &lt;span class=&#34;code-variable&#34;&gt;right-join-table&lt;/span&gt; ON &lt;span class=&#34;code-variable&#34;&gt;&lt;span class=&#34;code-variable&#34;&gt;&lt;a href=&#34;../../../../en/sql-reference/language-elements/predicates/interpolate/join-predicate/#&#34;&gt;join-predicate&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;
&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;

Omitting the keyword &lt;code&gt;OUTER&lt;/code&gt; from your statements does not affect results of left and right joins. &lt;code&gt;LEFT OUTER JOIN&lt;/code&gt; and &lt;code&gt;LEFT JOIN&lt;/code&gt; perform the same operation and return the same results.

&lt;/div&gt;
&lt;a name=&#34;LeftOuterJoin&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;left-outer-joins&#34;&gt;Left outer joins&lt;/h2&gt;
&lt;p&gt;A left outer join returns a complete set of records from the left-joined (preserved) table &lt;code&gt;T1&lt;/code&gt;, with matched records, where available, in the right-joined (non-preserved) table &lt;code&gt;T2&lt;/code&gt;. When the database finds no match, it extends the right side column (&lt;code&gt;T2&lt;/code&gt;) with null values.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM T1 LEFT OUTER JOIN T2 ON T1.x = T2.x;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To exclude the non-matched values from T2, write the same left outer join, but filter out the records you don&#39;t want from the right side by using a &lt;code&gt;WHERE&lt;/code&gt; clause:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM T1 LEFT OUTER JOIN T2
   ON T1.x = T2.x WHERE T2.x IS NOT NULL;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following example uses a left outer join to enrich telephone call detail records with an incomplete numbers dimension. It then filters out results that are known not to be from Massachusetts:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT COUNT(*) FROM calls LEFT OUTER JOIN numbers
   ON calls.to_phone = numbers.phone WHERE NVL(numbers.state, &amp;#39;&amp;#39;) &amp;lt;&amp;gt; &amp;#39;MA&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a name=&#34;RightOuterJoin&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;right-outer-joins&#34;&gt;Right outer joins&lt;/h2&gt;
&lt;p&gt;A right outer join returns a complete set of records from the right-joined (preserved) table, as well as matched values from the left-joined (non-preserved) table. If the database finds no matching records from the left-joined table (&lt;code&gt;T1&lt;/code&gt;), &lt;code&gt;NULL&lt;/code&gt; values appears in the &lt;code&gt;T1&lt;/code&gt; column for any records with no matching values in &lt;code&gt;T1&lt;/code&gt;. A right join is, therefore, similar to a left join, except that the treatment of the tables is reversed.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM T1 RIGHT OUTER JOIN T2 ON T1.x = T2.x;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The above query is equivalent to the following query, where &lt;code&gt;T1 RIGHT OUTER JOIN T2 = T2 LEFT OUTER JOIN T1&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM T2 LEFT OUTER JOIN T1 ON T2.x = T1.x;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following example identifies customers who have &lt;em&gt;not&lt;/em&gt; placed an order:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT customers.customer_id FROM orders RIGHT OUTER JOIN customers
   ON orders.customer_id = customers.customer_id
   GROUP BY customers.customer_id HAVING COUNT(orders.customer_id) = 0;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a name=&#34;FullOuterJoin&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;full-outer-joins&#34;&gt;Full outer joins&lt;/h2&gt;
&lt;p&gt;A full outer join returns results for both left and right outer joins. The joined table contains all records from both tables, including nulls (missing matches) from either side of the join. This is useful if you want to see, for example, each employee who is assigned to a particular department and each department that has an employee, but you also want to see all the employees who are not assigned to a particular department, as well as any department that has no employees:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT employee_last_name, hire_date FROM  employee_dimension emp
   FULL OUTER JOIN department dept ON emp.employee_key = dept.department_key;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;notes&#34;&gt;Notes&lt;/h2&gt;
&lt;p&gt;OpenText™ Analytics Database also supports joins where the outer (preserved) table or subquery is replicated on more than one node and the inner (non-preserved) table or subquery is segmented across more than one node. For example, in the following query, the fact table, which is almost always segmented, appears on the non-preserved side of the join, and it is allowed:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT sales_dollar_amount, transaction_type, customer_name
    FROM store.store_sales_fact f RIGHT JOIN customer_dimension d
   ON f.customer_key = d.customer_key;
 sales_dollar_amount | transaction_type | customer_name
---------------------+------------------+---------------
                 252 | purchase         | Inistar
                 363 | purchase         | Inistar
                 510 | purchase         | Inistar
                -276 | return           | Foodcorp
                 252 | purchase         | Foodcorp
                 195 | purchase         | Foodcorp
                 290 | purchase         | Foodcorp
                 222 | purchase         | Foodcorp
                     |                  | Foodgen
                     |                  | Goldcare
(10 rows)
&lt;/code&gt;&lt;/pre&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Controlling join inputs</title>
      <link>/en/data-analysis/queries/joins/controlling-join-inputs/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/joins/controlling-join-inputs/</guid>
      <description>
        
        
        &lt;p&gt;By default, the optimizer uses its own internal logic to determine whether to join one table to another as an inner or outer input. Occasionally, the optimizer might choose the larger table as the inner input to a join. Doing so can incur performance and concurrency issues.&lt;/p&gt;
&lt;p&gt;If the configuration parameter configuration parameter &lt;code&gt;EnableForceOuter&lt;/code&gt; is set to 1, you can control join inputs for specific tables through 
&lt;code&gt;&lt;a href=&#34;../../../../en/sql-reference/statements/alter-statements/alter-table/#&#34;&gt;ALTER TABLE..FORCE OUTER&lt;/a&gt;&lt;/code&gt;. The &lt;code&gt;FORCE OUTER&lt;/code&gt; option modifies a table&#39;s &lt;code&gt;force_outer&lt;/code&gt; setting in the system table 
&lt;code&gt;&lt;a href=&#34;../../../../en/sql-reference/system-tables/v-catalog-schema/tables/#&#34;&gt;TABLES&lt;/a&gt;&lt;/code&gt;. When implementing a join, the database compares the &lt;code&gt;force_outer&lt;/code&gt; settings of the participating tables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;If table settings are unequal, the database uses them to set the join inputs:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A table with a low &lt;code&gt;force_outer&lt;/code&gt; setting relative to other tables is joined to them as an inner input.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A table with a high &lt;code&gt;force_outer&lt;/code&gt; setting relative to other tables is joined to them as an outer input.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If all table settings are equal, the database ignores them and assembles the join on its own.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;force_outer&lt;/code&gt; column is initially set to 5 for all newly-defined tables. You can use 
&lt;code&gt;&lt;a href=&#34;../../../../en/sql-reference/statements/alter-statements/alter-table/#&#34;&gt;ALTER TABLE..FORCE OUTER&lt;/a&gt;&lt;/code&gt; to reset &lt;code&gt;force_outer&lt;/code&gt; to a value equal to or greater than 0. For example, you might change the &lt;code&gt;force_outer&lt;/code&gt; settings of tables &lt;code&gt;abc&lt;/code&gt; and &lt;code&gt;xyz&lt;/code&gt; to 3 and 8, respectively:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER TABLE abc FORCE OUTER 3;
=&amp;gt; ALTER TABLE xyz FORCE OUTER 8;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Given these settings, the optimizer joins &lt;code&gt;abc&lt;/code&gt; as the inner input to any table with a &lt;code&gt;force_outer&lt;/code&gt; value greater than 3. The optimizer joins &lt;code&gt;xyz&lt;/code&gt; as the outer input to any table with a &lt;code&gt;force_outer&lt;/code&gt; value less than 8.&lt;/p&gt;
&lt;h2 id=&#34;projection-inheritance&#34;&gt;Projection inheritance&lt;/h2&gt;
&lt;p&gt;When you query a projection directly, it inherits the &lt;code&gt;force_outer&lt;/code&gt; setting of its anchor table. The query then uses this setting when joined to another projection.&lt;/p&gt;
&lt;h2 id=&#34;enabling-forced-join-inputs&#34;&gt;Enabling forced join inputs&lt;/h2&gt;
&lt;p&gt;The configuration parameter &lt;code&gt;EnableForceOuter&lt;/code&gt; determines whether the database uses a table&#39;s &lt;code&gt;force_outer&lt;/code&gt; value to implement a join. By default, this parameter is set to 0, and forced join inputs are disabled. You can enable forced join inputs at session and database scopes, through 
&lt;code&gt;&lt;a href=&#34;../../../../en/sql-reference/statements/alter-statements/alter-session/#&#34;&gt;ALTER SESSION&lt;/a&gt;&lt;/code&gt; and 
&lt;code&gt;&lt;a href=&#34;../../../../en/sql-reference/statements/alter-statements/alter-db/#&#34;&gt;ALTER DATABASE&lt;/a&gt;&lt;/code&gt;, respectively:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER SESSION SET EnableForceOuter = { 0 | 1 };
=&amp;gt; ALTER DATABASE &lt;span class=&#34;code-variable&#34;&gt;db-name&lt;/span&gt; SET EnableForceOuter =  { 0 | 1 };
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If &lt;code&gt;EnableForceOuter&lt;/code&gt; is set to 0, &lt;code&gt;ALTER TABLE..FORCE OUTER&lt;/code&gt; statements return with this warning:

&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;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;WARNING 0: Set configuration parameter EnableForceOuter for the current session or the database in order to use
force_outer value
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote&gt;
&lt;/blockquote&gt;


&lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&#34;viewing-forced-join-inputs&#34;&gt;Viewing forced join inputs&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;EXPLAIN&lt;/code&gt;-generated query plans indicate whether the configuration parameter &lt;code&gt;EnableForceOuter&lt;/code&gt; is on. A join query might include tables whose &lt;code&gt;force_outer&lt;/code&gt; settings are less or greater than the default value of 5. In this case, the query plan includes a &lt;code&gt;Force outer level&lt;/code&gt; field for the relevant join inputs.&lt;/p&gt;
&lt;p&gt;For example, the following query joins tables &lt;code&gt;store.store_sales&lt;/code&gt; and &lt;code&gt;public.products&lt;/code&gt;, where both tables have the same &lt;code&gt;force_outer&lt;/code&gt; setting (5). &lt;code&gt;EnableForceOuter&lt;/code&gt; is on, as indicated in the generated query plan:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT s.store_key, p.product_description, s.sales_quantity, s.sale_date
   FROM store.store_sales s JOIN public.products p ON s.product_key=p.product_key
   WHERE s.sale_date=&amp;#39;2014-12-01&amp;#39; ORDER BY s.store_key, s.sale_date;

 EnableForceOuter is on
 Access Path:
 +-SORT [Cost: 7K, Rows: 100K (NO STATISTICS)] (PATH ID: 1)
 |  Order: sales.store_key ASC, sales.sale_date ASC
 |  Execute on: All Nodes
 | +---&amp;gt; JOIN HASH [Cost: 5K, Rows: 100K (NO STATISTICS)] (PATH ID: 2) Outer (BROADCAST)(LOCAL ROUND ROBIN)
 | |      Join Cond: (sales.product_key = products.product_key)
 | |      Execute on: All Nodes
 | | +-- Outer -&amp;gt; STORAGE ACCESS for sales [Cost: 2K, Rows: 100K (NO STATISTICS)] (PATH ID: 3)
 | | |      Projection: store.store_sales_b0
 | | |      Materialize: sales.sale_date, sales.store_key, sales.product_key, sales.sales_quantity
 | | |      Filter: (sales.sale_date = &amp;#39;2014-12-01&amp;#39;::date)
 | | |      Execute on: All Nodes
 | | +-- Inner -&amp;gt; STORAGE ACCESS for products [Cost: 177, Rows: 60K (NO STATISTICS)] (PATH ID: 4)
 | | |      Projection: public.products_b0
 | | |      Materialize: products.product_key, products.product_description
 | | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following &lt;code&gt;ALTER TABLE&lt;/code&gt; statement resets the &lt;code&gt;force_outer&lt;/code&gt; setting of &lt;code&gt;public.products&lt;/code&gt; to 1:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER TABLE public.products FORCE OUTER 1;
ALTER TABLE
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The regenerated query plan for the same join now includes a &lt;code&gt;Force outer level&lt;/code&gt; field and specifies &lt;code&gt;public.products&lt;/code&gt; as the inner input:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; EXPLAIN SELECT s.store_key, p.product_description, s.sales_quantity, s.sale_date
   FROM store.store_sales s JOIN public.products p ON s.product_key=p.product_key
   WHERE s.sale_date=&amp;#39;2014-12-01&amp;#39; ORDER BY s.store_key, s.sale_date;

 EnableForceOuter is on
 Access Path:
 +-SORT [Cost: 7K, Rows: 100K (NO STATISTICS)] (PATH ID: 1)
 |  Order: sales.store_key ASC, sales.sale_date ASC
 |  Execute on: All Nodes
 | +---&amp;gt; JOIN HASH [Cost: 5K, Rows: 100K (NO STATISTICS)] (PATH ID: 2) Outer (BROADCAST)(LOCAL ROUND ROBIN)
 | |      Join Cond: (sales.product_key = products.product_key)
 | |      Execute on: All Nodes
 | | +-- Outer -&amp;gt; STORAGE ACCESS for sales [Cost: 2K, Rows: 100K (NO STATISTICS)] (PATH ID: 3)
 | | |      Projection: store.store_sales_b0
 | | |      Materialize: sales.sale_date, sales.store_key, sales.product_key, sales.sales_quantity
 | | |      Filter: (sales.sale_date = &amp;#39;2014-12-01&amp;#39;::date)
 | | |      Execute on: All Nodes
 | | +-- I&lt;span class=&#34;code-input&#34;&gt;nner -&gt; STORAGE ACCESS for products&lt;/span&gt; [Cost: 177, Rows: 60K (NO STATISTICS)] (PATH ID: 4)
 | | |      &lt;span class=&#34;code-input&#34;&gt;Projection: public.products_b0&lt;/span&gt;
 | | |      Force outer level: 1
 | | |      Materialize: products.product_key, products.product_description
 | | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you change the &lt;code&gt;force_outer&lt;/code&gt; setting of &lt;code&gt;public.products&lt;/code&gt; to 8, the database creates a different query plan that specifies &lt;code&gt;public.products&lt;/code&gt; as the outer input:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER TABLE public.products FORCE OUTER 8;
ALTER TABLE

=&amp;gt; EXPLAIN SELECT s.store_key, p.product_description, s.sales_quantity, s.sale_date
   FROM store.store_sales s JOIN public.products p ON s.product_key=p.product_key
   WHERE s.sale_date=&amp;#39;2014-12-01&amp;#39; ORDER BY s.store_key, s.sale_date;


EnableForceOuter is on
 Access Path:
 +-SORT [Cost: 7K, Rows: 100K (NO STATISTICS)] (PATH ID: 1)
 |  Order: sales.store_key ASC, sales.sale_date ASC
 |  Execute on: All Nodes
 | +---&amp;gt; JOIN HASH [Cost: 5K, Rows: 100K (NO STATISTICS)] (PATH ID: 2) Inner (BROADCAST)
 | |      Join Cond: (sales.product_key = products.product_key)
 | |      Materialize at Output: products.product_description
 | |      Execute on: All Nodes
 | | +-- &lt;span class=&#34;code-input&#34;&gt;Outer -&gt; STORAGE ACCESS for products&lt;/span&gt; [Cost: 20, Rows: 60K (NO STATISTICS)] (PATH ID: 3)
 | | |      &lt;span class=&#34;code-input&#34;&gt;Projection: public.products_b0&lt;/span&gt;
 | | |      &lt;span class=&#34;code-input&#34;&gt;Force outer level: 8&lt;/span&gt;
 | | |      Materialize: products.product_key
 | | |      Execute on: All Nodes
 | | |      Runtime Filter: (SIP1(HashJoin): products.product_key)
 | | +-- Inner -&amp;gt; STORAGE ACCESS for sales [Cost: 2K, Rows: 100K (NO STATISTICS)] (PATH ID: 4)
 | | |      Projection: store.store_sales_b0
 | | |      Materialize: sales.sale_date, sales.store_key, sales.product_key, sales.sales_quantity
 | | |      Filter: (sales.sale_date = &amp;#39;2014-12-01&amp;#39;::date)
 | | |      Execute on: All Nodes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a name=&#34;Restrictions&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;restrictions&#34;&gt;Restrictions&lt;/h2&gt;
&lt;p&gt;The database ignores &lt;code&gt;force_outer&lt;/code&gt; settings when it performs the following operations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Outer joins: the database generally respects &lt;code&gt;OUTER JOIN&lt;/code&gt; clauses regardless of the &lt;code&gt;force_outer&lt;/code&gt; settings of the joined tables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;
&lt;code&gt;&lt;a href=&#34;../../../../en/sql-reference/statements/merge/#&#34;&gt;MERGE&lt;/a&gt;&lt;/code&gt; statement joins.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Queries that include the 
&lt;code&gt;&lt;a href=&#34;../../../../en/sql-reference/language-elements/hints/syntactic-join/#&#34;&gt;SYNTACTIC_JOIN&lt;/a&gt;&lt;/code&gt; hint.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Half-join queries such as 
&lt;code&gt;&lt;a href=&#34;../../../../en/admin/managing-queries/directed-queries/half-join-and-cross-join-semantics/half-join-subquery-semantics/#SEMI&#34;&gt;SEMI JOIN&lt;/a&gt;&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Joins to subqueries, where the subquery is always processed as having a &lt;code&gt;force_outer&lt;/code&gt; setting of 5 regardless of the &lt;code&gt;force_outer&lt;/code&gt; settings of the tables that are joined in the subquery. This setting determines a subquery&#39;s designation as inner or outer input relative to other join inputs. If two subqueries are joined, the optimizer determines which one is the inner input, and which one the outer.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Range joins</title>
      <link>/en/data-analysis/queries/joins/range-joins/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/joins/range-joins/</guid>
      <description>
        
        
        &lt;p&gt;OpenText™ Analytics Database provides performance optimizations for &amp;lt;, &amp;lt;=, &amp;gt;, &amp;gt;=, and &lt;code&gt;BETWEEN&lt;/code&gt; predicates in join &lt;code&gt;ON&lt;/code&gt; clauses. These optimizations are particularly useful when a column from one table is restricted to be in a range specified by two columns of another table.&lt;/p&gt;
&lt;h2 id=&#34;key-ranges&#34;&gt;Key ranges&lt;/h2&gt;
&lt;p&gt;Multiple, consecutive key values can map to the same dimension values. Consider, for example, a table of IPv4 addresses and their owners. Because large subnets (ranges) of IP addresses can belong to the same owner, this dimension can be represented as:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE TABLE ip_owners(
      ip_start INTEGER,
      ip_end INTEGER,
      owner_id INTEGER);
=&amp;gt; CREATE TABLE clicks(
      ip_owners INTEGER,
      dest_ip INTEGER);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A query that associates a click stream with its destination can use a join similar to the following, which takes advantage of range optimization:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT owner_id, COUNT(*) FROM clicks JOIN ip_owners
   ON clicks.dest_ip BETWEEN ip_start AND ip_end
   GROUP BY owner_id;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;requirements&#34;&gt;Requirements&lt;/h2&gt;
&lt;p&gt;Operators &amp;lt;, &amp;lt;=, &amp;gt;, &amp;gt;=, or &lt;code&gt;BETWEEN&lt;/code&gt; must appear as top-level conjunctive predicates for range join optimization to be effective, as shown in the following examples:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;`BETWEEN` as the only predicate:

```
=&amp;gt; SELECT COUNT(*) FROM fact JOIN dim
    ON fact.point BETWEEN dim.start AND dim.end;

```

Comparison operators as top-level predicates (within `AND`):

```
=&amp;gt; SELECT COUNT(*) FROM fact JOIN dim
    ON fact.point &amp;gt; dim.start AND fact.point &amp;lt; dim.end;

```

`BETWEEN` as a top-level predicate (within `AND`):

```
=&amp;gt; SELECT COUNT(*) FROM fact JOIN dim
   ON (fact.point BETWEEN dim.start AND dim.end) AND fact.c &amp;lt;&amp;gt; dim.c;

```

Query not optimized because `OR` is top-level predicate (disjunctive):

```
=&amp;gt; SELECT COUNT(*) FROM fact JOIN dim
   ON (fact.point BETWEEN dim.start AND dim.end) OR dim.end IS NULL;

```
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;notes&#34;&gt;Notes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Expressions are optimized in range join queries in many cases.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If range columns can have &lt;code&gt;NULL&lt;/code&gt; values indicating that they are open-ended, it is possible to use range join optimizations by replacing nulls with very large or very small values:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT COUNT(*) FROM fact JOIN dim
   ON fact.point BETWEEN NVL(dim.start, -1) AND NVL(dim.end, 1000000000000);
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If there is more than one set of ranging predicates in the same &lt;code&gt;ON&lt;/code&gt; clause, the order in which the predicates are specified might impact the effectiveness of the optimization:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT COUNT(*) FROM fact JOIN dim ON fact.point1 BETWEEN dim.start1 AND dim.end1
   AND fact.point2 BETWEEN dim.start2 AND dim.end2;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The optimizer chooses the first range to optimize, so write your queries so that the range you most want optimized appears first in the statement.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The use of the range join optimization is not directly affected by any characteristics of the physical schema; no schema tuning is required to benefit from the optimization.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The range join optimization can be applied to joins without any other predicates, and to &lt;code&gt;HASH&lt;/code&gt; or &lt;code&gt;MERGE&lt;/code&gt; joins.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To determine if an optimization is in use, search for &lt;code&gt;RANGE&lt;/code&gt; in the &lt;code&gt;EXPLAIN&lt;/code&gt; plan.
&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Event series joins</title>
      <link>/en/data-analysis/queries/joins/event-series-joins/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/joins/event-series-joins/</guid>
      <description>
        
        
        &lt;p&gt;A &lt;a class=&#34;glosslink&#34; href=&#34;../../../../en/glossary/event-series/&#34; title=&#34;Tables with a time column, most typically a timestamp data type.&#34;&gt;event series&lt;/a&gt; join is an SQL extension that enables the analysis of two series when their measurement intervals don’t align precisely, such as with mismatched timestamps. You can compare values from the two series directly, rather than having to normalize the series to the same measurement interval.&lt;/p&gt;
&lt;p&gt;Event series joins are an extension of &lt;a href=&#34;../../../../en/data-analysis/queries/joins/outer-joins/#&#34;&gt;Outer joins&lt;/a&gt;, but instead of padding the non-preserved side with NULL values when there is no match, the event series join pads the non-preserved side values that it interpolates from either the previous or next value, whichever is specified in the query.&lt;/p&gt;
&lt;p&gt;The difference in how you write a regular join versus an event series join is the INTERPOLATE predicate, which is used in the ON clause. For example, the following two statements show the differences, which are shown in greater detail in &lt;a href=&#34;../../../../en/data-analysis/queries/joins/event-series-joins/writing-event-series-joins/#&#34;&gt;Writing event series joins&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;h3 id=&#34;regular-full-outer-join&#34;&gt;Regular full outer join&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT * FROM hTicks h FULL OUTER JOIN aTicks a
ON (h.time = a.time);
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id=&#34;event-series-join&#34;&gt;Event series join&lt;/h3&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;SELECT * FROM hTicks h FULL OUTER JOIN aTicks a
ON (h.time INTERPOLATE PREVIOUS VALUE a.time);
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Similar to regular joins, an event series join has inner and outer join modes, which are described in the topics that follow.&lt;/p&gt;
&lt;p&gt;For full syntax, including notes and restrictions, see &lt;a href=&#34;../../../../en/sql-reference/language-elements/predicates/interpolate/#&#34;&gt;INTERPOLATE&lt;/a&gt;&lt;/p&gt;

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