<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>OpenText Analytics Database 26.2.x – Queries</title>
    <link>/en/data-analysis/queries/</link>
    <description>Recent content in Queries on OpenText Analytics Database 26.2.x</description>
    <generator>Hugo -- gohugo.io</generator>
    
	  <atom:link href="/en/data-analysis/queries/index.xml" rel="self" type="application/rss+xml" />
    
    
      
        
      
    
    
    <item>
      <title>Data-Analysis: Historical queries</title>
      <link>/en/data-analysis/queries/historical-queries/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/historical-queries/</guid>
      <description>
        
        
        &lt;p&gt;OpenText™ Analytics Database can execute historical queries, which execute on a snapshot of the database taken at a specific timestamp or epoch. Historical queries can be used to evaluate and possibly recover data that was deleted but has not yet been &lt;a href=&#34;../../../en/admin/working-with-native-tables/removing-table-data/purging-deleted-data/&#34;&gt;purged&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You specify a historical query by qualifying the 
&lt;code&gt;&lt;a href=&#34;../../../en/sql-reference/statements/select/#&#34;&gt;SELECT&lt;/a&gt;&lt;/code&gt; statement with an &lt;code&gt;AT &lt;/code&gt;&lt;em&gt;&lt;code&gt;epoch&lt;/code&gt;&lt;/em&gt; clause, where &lt;em&gt;&lt;code&gt;epoch&lt;/code&gt;&lt;/em&gt; is one of the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;EPOCH LATEST&lt;/code&gt;: Return data up to but not including the current epoch. The result set includes data from the latest committed DML transaction.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;EPOCH &lt;/code&gt;&lt;em&gt;&lt;code&gt;integer&lt;/code&gt;&lt;/em&gt;: Return data up to and including the specified epoch.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;TIME &#39;&lt;/code&gt;&lt;em&gt;&lt;code&gt;timestamp&lt;/code&gt;&lt;/em&gt;&lt;code&gt;&#39;&lt;/code&gt;: Return data from the epoch at the specified timestamp.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These options are ignored if used to query temporary or external tables.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;../../../en/admin/failure-recovery/epochs/#&#34;&gt;Epochs&lt;/a&gt; for additional information about how OpenText™ Analytics Database uses epochs.&lt;/p&gt;

&lt;p&gt;Historical queries return data only from the specified epoch. Because they do not return the latest data, historical queries hold no locks or blocking write operations.&lt;/p&gt;
&lt;p&gt;Query results are private to the transaction and valid only for the length of the transaction. Query execution is the same regardless of the transaction isolation level.&lt;/p&gt;
&lt;h2 id=&#34;restrictions&#34;&gt;Restrictions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The specified epoch, or epoch of the specified timestamp, cannot be less than the &lt;a class=&#34;glosslink&#34; href=&#34;../../../en/glossary/ancient-history-mark-ahm/&#34; title=&#34;Also known as AHM, the ancient history mark is the oldest epoch whose data is accessible to historical queries.&#34;&gt;Ancient History Mark&lt;/a&gt; epoch.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;OpenText™ Analytics Database does not support running historical queries on temporary tables.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&#34;admonition important&#34; role=&#34;alert&#34;&gt;
&lt;h4 class=&#34;admonition-head&#34;&gt;Important&lt;/h4&gt;
Any changes to a table schema are reflected across all epochs. For example, if you add a column to a table and specify a default value for it, all historical queries on that table display the new column and its default value.
&lt;/div&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Temporary tables</title>
      <link>/en/data-analysis/queries/temporary-tables/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/temporary-tables/</guid>
      <description>
        
        
        &lt;p&gt;You can use the &lt;code&gt;CREATE TEMPORARY TABLE&lt;/code&gt; statement to implement certain queries using multiple steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Create one or more temporary tables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute queries and store the result sets in the temporary tables.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Execute the main query using the temporary tables as if they were a normal part of the &lt;a class=&#34;glosslink&#34; href=&#34;../../../en/glossary/logical-schema/&#34; title=&#34;Consists of a set of tables and referential integrity constraints in an OpenText&amp;amp;trade; Analytics Database.&#34;&gt;logical schema&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;See &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-temporary-table/&#34;&gt;&lt;code&gt;CREATE TEMPORARY TABLE&lt;/code&gt;&lt;/a&gt; in the SQL Reference Manual for details.
&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: SQL queries</title>
      <link>/en/data-analysis/queries/sql-queries/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/sql-queries/</guid>
      <description>
        
        
        &lt;p&gt;All DML (Data Manipulation Language) statements can contain queries. This section introduces some of the query types in OpenText™ Analytics Database, with additional details in later sections.

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

Many of the examples in this chapter use the &lt;a href=&#34;../../../en/getting-started/introducing-vmart-example-db/&#34;&gt;VMart schema&lt;/a&gt;.

&lt;/div&gt;&lt;/p&gt;
&lt;h2 id=&#34;simple-queries&#34;&gt;Simple queries&lt;/h2&gt;
&lt;p&gt;Simple queries contain a query against one table. Minimal effort is required to process the following query, which looks for product keys and SKU numbers in the product table:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT product_key, sku_number FROM public.product_dimension;
product_key  | sku_number
-------------+-----------
43           | SKU-#129
87           | SKU-#250
42           | SKU-#125
49           | SKU-#154
37           | SKU-#107
36           | SKU-#106
86           | SKU-#248
41           | SKU-#121
88           | SKU-#257
40           | SKU-#120
(10 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Tables can contain arrays. You can select the entire array column, an index into it, or the results of a function applied to the array. For more information, see &lt;a href=&#34;../../../en/data-analysis/queries/arrays-and-sets-collections/#&#34;&gt;Arrays and sets (collections)&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;joins&#34;&gt;Joins&lt;/h2&gt;
&lt;p&gt;Joins use a relational operator that combines information from two or more tables. The query&#39;s &lt;code&gt;ON&lt;/code&gt; clause specifies how tables are combined, such as by matching foreign keys to primary keys. In the following example, the query requests the names of stores with transactions greater than 70 by joining the store key ID from the store schema&#39;s sales fact and sales tables:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT store_name, COUNT(*) FROM store.store_sales_fact
   JOIN store.store_dimension ON store.store_sales_fact.store_key = store.store_dimension.store_key
   GROUP BY store_name HAVING COUNT(*) &amp;gt; 70 ORDER BY store_name;

 store_name | count
------------+-------
 Store49    |    72
 Store83    |    78
(2 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For more detailed information, see &lt;a href=&#34;../../../en/data-analysis/queries/joins/#&#34;&gt;Joins&lt;/a&gt;. See also the Multicolumn subqueries section in &lt;a href=&#34;../../../en/data-analysis/queries/subqueries/subquery-examples/#&#34;&gt;Subquery examples&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;cross-joins&#34;&gt;Cross joins&lt;/h2&gt;
&lt;p&gt;Also known as the Cartesian product, a cross join is the result of joining every record in one table with every record in another table. A cross join occurs when there is no join key between tables to restrict records. The following query, for example, returns all instances of vendor and store names in the vendor and store tables:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT vendor_name, store_name FROM public.vendor_dimension
    CROSS JOIN store.store_dimension;
vendor_name         | store_name
--------------------+------------
Deal Warehouse      | Store41
Deal Warehouse      | Store12
Deal Warehouse      | Store46
Deal Warehouse      | Store50
Deal Warehouse      | Store15
Deal Warehouse      | Store48
Deal Warehouse      | Store39
Sundry Wholesale    | Store41
Sundry Wholesale    | Store12
Sundry Wholesale    | Store46
Sundry Wholesale    | Store50
Sundry Wholesale    | Store15
Sundry Wholesale    | Store48
Sundry Wholesale    | Store39
Market Discounters  | Store41
Market Discounters  | Store12
Market Discounters  | Store46
Market Discounters  | Store50
Market Discounters  | Store15
Market Discounters  | Store48
Market Discounters  | Store39
Market Suppliers    | Store41
Market Suppliers    | Store12
Market Suppliers    | Store46
Market Suppliers    | Store50
Market Suppliers    | Store15
Market Suppliers    | Store48
Market Suppliers    | Store39
...                 | ...
(4000 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This example&#39;s output is truncated because this particular cross join returned several thousand rows. See also &lt;a href=&#34;../../../en/data-analysis/queries/joins/inner-joins/cross-joins/#&#34;&gt;Cross joins&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;subqueries&#34;&gt;Subqueries&lt;/h2&gt;
&lt;p&gt;A subquery is a query nested within another query. In the following example, we want a list of all products containing the highest fat content. The inner query (subquery) returns the product containing the highest fat content among all food products to the outer query block (containing query). The outer query then uses that information to return the names of the products containing the highest fat content.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT product_description, fat_content FROM public.product_dimension
   WHERE fat_content IN
     (SELECT MAX(fat_content) FROM public.product_dimension
      WHERE category_description = &amp;#39;Food&amp;#39; AND department_description = &amp;#39;Bakery&amp;#39;)
   LIMIT 10;
         product_description         | fat_content
-------------------------------------+-------------
 Brand #59110 hotdog buns            |          90
 Brand #58107 english muffins        |          90
 Brand #57135 english muffins        |          90
 Brand #54870 cinnamon buns          |          90
 Brand #53690 english muffins        |          90
 Brand #53096 bagels                 |          90
 Brand #50678 chocolate chip cookies |          90
 Brand #49269 wheat bread            |          90
 Brand #47156 coffee cake            |          90
 Brand #43844 corn muffins           |          90
(10 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For more information, see &lt;a href=&#34;../../../en/data-analysis/queries/subqueries/#&#34;&gt;Subqueries&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;sorting-queries&#34;&gt;Sorting queries&lt;/h2&gt;
&lt;p&gt;Use the &lt;code&gt;ORDER BY&lt;/code&gt; clause to order the rows that a query returns.&lt;/p&gt;
&lt;h2 id=&#34;special-note-about-query-results&#34;&gt;Special note about query results&lt;/h2&gt;
&lt;p&gt;You could get different results running certain queries on one machine or another for the following reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/admin/partitioning-tables/&#34;&gt;Partitioning&lt;/a&gt; on a &lt;code&gt;FLOAT&lt;/code&gt; type could return nondeterministic results because of the precision, especially when the numbers are close to one another, such as results from the &lt;code&gt;RADIANS()&lt;/code&gt; function, which has a very small range of output.&lt;/p&gt;
&lt;p&gt;To get deterministic results, use &lt;code&gt;NUMERIC&lt;/code&gt; if you must partition by data that is not an &lt;code&gt;INTEGER&lt;/code&gt; type.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Most analytics (with analytic aggregations, such as &lt;code&gt;MIN()/MAX()/SUM()/COUNT()/AVG()&lt;/code&gt; as exceptions) rely on a unique order of input data to get deterministic result. If the analytic &lt;a href=&#34;../../../en/data-analysis/sql-analytics/window-ordering/&#34;&gt;window-order&lt;/a&gt; clause cannot resolve ties in the data, results could be different each time you run the query.&lt;/p&gt;
&lt;p&gt;For example, in the following query, the analytic &lt;code&gt;ORDER BY&lt;/code&gt; does not include the first column in the query, &lt;code&gt;promotion_key&lt;/code&gt;. So for a tie of &lt;code&gt;AVG(RADIANS(cost_dollar_amount)), product_version&lt;/code&gt;, the same &lt;code&gt;promotion_key&lt;/code&gt; could have different positions within the analytic partition, resulting in a different &lt;code&gt;NTILE()&lt;/code&gt; number. Thus, &lt;code&gt;DISTINCT&lt;/code&gt; could also have a different result:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT COUNT(*) FROM
      (SELECT DISTINCT SIN(FLOOR(MAX(store.store_sales_fact.promotion_key))),
   NTILE(79) OVER(PARTITION BY AVG (RADIANS
      (store.store_sales_fact.cost_dollar_amount ))
   ORDER BY store.store_sales_fact.product_version)
   FROM store.store_sales_fact
   GROUP BY store.store_sales_fact.product_version,
         store.store_sales_fact.sales_dollar_amount ) AS store;
 count
-------
  1425
(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you add &lt;code&gt;MAX(promotion_key)&lt;/code&gt; to analytic &lt;code&gt;ORDER BY&lt;/code&gt;, the results are the same on any machine:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT COUNT(*) FROM (SELECT DISTINCT MAX(store.store_sales_fact.promotion_key),
    NTILE(79) OVER(PARTITION BY MAX(store.store_sales_fact.cost_dollar_amount)
   ORDER BY store.store_sales_fact.product_version,
   MAX(store.store_sales_fact.promotion_key))
   FROM store.store_sales_fact
   GROUP BY store.store_sales_fact.product_version,
     store.store_sales_fact.sales_dollar_amount) AS store;
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Arrays and sets (collections)</title>
      <link>/en/data-analysis/queries/arrays-and-sets-collections/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/arrays-and-sets-collections/</guid>
      <description>
        
        
        &lt;p&gt;Tables can include collections (arrays or sets). An &lt;a href=&#34;../../../en/sql-reference/data-types/complex-types/array/#&#34;&gt;ARRAY&lt;/a&gt; is an ordered collection of elements that allows duplicate values, and a &lt;a href=&#34;../../../en/sql-reference/data-types/complex-types/set/#&#34;&gt;SET&lt;/a&gt; is an unordered collection of unique values.&lt;/p&gt;
&lt;p&gt;Consider an orders table with columns for product keys, customer keys, order prices, and order date, with some containing arrays. A basic query results in the following:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM orders LIMIT 5;
 orderkey | custkey |        prodkey         |         orderprices         | orderdate
----------+---------+------------------------+-----------------------------+------------
    19626 |      91 | [&amp;#34;P1262&amp;#34;,&amp;#34;P68&amp;#34;,&amp;#34;P101&amp;#34;] | [&amp;#34;192.59&amp;#34;,&amp;#34;49.99&amp;#34;,&amp;#34;137.49&amp;#34;] | 2021-03-14
    25646 |     716 | [&amp;#34;P997&amp;#34;,&amp;#34;P31&amp;#34;,&amp;#34;P101&amp;#34;]  | [&amp;#34;91.39&amp;#34;,&amp;#34;29.99&amp;#34;,&amp;#34;147.49&amp;#34;]  | 2021-03-14
    25647 |     716 | [&amp;#34;P12&amp;#34;]                | [&amp;#34;8.99&amp;#34;]                    | 2021-03-14
    19743 |     161 | [&amp;#34;P68&amp;#34;,&amp;#34;P101&amp;#34;]         | [&amp;#34;49.99&amp;#34;,&amp;#34;137.49&amp;#34;]          | 2021-03-15
    19888 |     241 | [&amp;#34;P1262&amp;#34;,&amp;#34;P101&amp;#34;]       | [&amp;#34;197.59&amp;#34;,&amp;#34;142.49&amp;#34;]         | 2021-03-15
(5 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As shown in this example, array values are returned in &lt;a href=&#34;https://www.w3schools.com/js/js_json_arrays.asp&#34;&gt;JSON format&lt;/a&gt;. Set values are also returned in JSON array format.&lt;/p&gt;
&lt;p&gt;You can access elements of nested arrays (multi-dimensional arrays) with multiple indexes:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT host, pingtimes FROM network_tests;
 host |                 pingtimes
------+-------------------------------------------------------
 eng1 | [[24.24,25.27,27.16,24.97], [23.97,25.01,28.12,29.50]]
 eng2 | [[27.12,27.91,28.11,26.95], [29.01,28.99,30.11,31.56]]
 qa1  | [[23.15,25.11,24.63,23.91], [22.85,22.86,23.91,31.52]]
(3 rows)

=&amp;gt; SELECT pingtimes[0] FROM network_tests;
      pingtimes
-------------------------
[24.24,25.27,27.16,24.97]
[27.12,27.91,28.11,26.95]
[23.15,25.11,24.63,23.91]
(3 rows)

=&amp;gt; SELECT pingtimes[0][0] FROM network_tests;
 pingtimes
-----------
24.24
27.12
23.15
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;OpenText™ Analytics Database supports several &lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/&#34;&gt;functions&lt;/a&gt; to manipulate arrays and sets.&lt;/p&gt;
&lt;p&gt;Consider the orders table, which has an array of product keys for all items purchased in a single order. You can use the &lt;span class=&#34;sql&#34;&gt;APPLY_COUNT_ELEMENTS&lt;/span&gt; function to find out how many items each order contains (excluding null values):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT APPLY_COUNT_ELEMENTS(prodkey) FROM orders LIMIT 5;
apply_count_elements
--------------------
3
2
2
3
1
(5 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;OpenText™ Analytics Database also supports aggregate functions for collections. Consider a column with an array of prices for items purchased in a single order. You can use the &lt;span class=&#34;sql&#34;&gt;APPLY_SUM&lt;/span&gt; function to find the total amount spent for each order:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT APPLY_SUM(orderprices) FROM orders LIMIT 5;
apply_sum
-----------
380.07
187.48
340.08
268.87
  8.99
(5 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Most of the array functions operate only on one-dimensional arrays. To use them with multi-dimensional arrays, first dereference one dimension:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT APPLY_MAX(pingtimes[0]) FROM network_tests;
 apply_max
-----------
 27.16
 28.11
 25.11
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See &lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/#&#34;&gt;Collection functions&lt;/a&gt; for a comprehensive list of functions.&lt;/p&gt;
&lt;p&gt;You can include both column names and literal values in queries. The following example returns the product keys for orders where the number of items in each order is three or more:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT prodkey FROM orders WHERE APPLY_COUNT_ELEMENTS(prodkey)&amp;gt;2;
      prodkey
------------------------
 [&amp;#34;P1262&amp;#34;,&amp;#34;P68&amp;#34;,&amp;#34;P101&amp;#34;]
 [&amp;#34;P997&amp;#34;,&amp;#34;P31&amp;#34;,&amp;#34;P101&amp;#34;]
(2 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can use aggregate functions in a WHERE clause:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT custkey, cust_custname, cust_email, orderkey, prodkey, orderprices FROM orders
 JOIN cust ON custkey = cust_custkey
 WHERE APPLY_SUM(orderprices)&amp;gt;150 ;
custkey|  cust_custname   |        cust_email         |   orderkey   |                  prodkey                  |        orderprices
-------+------------------+---------------------------+--------------+--------------------------------========---+---------------------------
342799 | &amp;#34;Ananya Patel&amp;#34;   | &amp;#34;ananyapatel98@gmail.com&amp;#34; | &amp;#34;113-341987&amp;#34; | [&amp;#34;MG-7190&amp;#34;,&amp;#34;VA-4028&amp;#34;,&amp;#34;EH-1247&amp;#34;,&amp;#34;MS-7018&amp;#34;] | [60.00,67.00,22.00,14.99]
342845 | &amp;#34;Molly Benton&amp;#34;   | &amp;#34;molly_benton@gmail.com&amp;#34;  | &amp;#34;111-952000&amp;#34; | [&amp;#34;ID-2586&amp;#34;,&amp;#34;IC-9010&amp;#34;,&amp;#34;MH-2401&amp;#34;,&amp;#34;JC-1905&amp;#34;] | [22.00,35.00,90.00,12.00]
342989 | &amp;#34;Natasha Abbasi&amp;#34; | &amp;#34;natsabbasi@live.com&amp;#34;     | &amp;#34;111-685238&amp;#34; | [&amp;#34;HP-4024&amp;#34;]                               | [650.00]
342176 | &amp;#34;Jose Martinez&amp;#34;  | &amp;#34;jmartinez@hotmail.com&amp;#34;   | &amp;#34;113-672238&amp;#34; | [&amp;#34;HP-4768&amp;#34;,&amp;#34;IC-9010&amp;#34;]                     | [899.00,60.00]
342845 | &amp;#34;Molly Benton&amp;#34;   | &amp;#34;molly_benton@gmail.com&amp;#34;  | &amp;#34;113-864153&amp;#34; | [&amp;#34;AE-7064&amp;#34;,&amp;#34;VA-4028&amp;#34;,&amp;#34;GW-1808&amp;#34;]           | [72.00,99.00,185.00]
(5 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;element-data-types&#34;&gt;Element data types&lt;/h2&gt;
&lt;p&gt;Collections support elements of any scalar type, arrays, or structs (ROW). In the following version of the orders table, an array of ROW elements contains information about all shipments for an order:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE TABLE orders(
  orderid INT,
  accountid INT,
  shipments ARRAY[
    ROW(
      shipid INT,
      address ROW(
        street VARCHAR,
        city VARCHAR,
        zip INT
        ),
      shipdate DATE
    )
  ]
 );
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Some orders consist of more than one shipment. Line breaks have been inserted into the following output for legibility:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM orders;
 orderid | accountid |                          shipments
---------+-----------+---------------------------------------------------------------------------------------------------------------
   99123 |        17 | [{&amp;#34;shipid&amp;#34;:1,&amp;#34;address&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;911 San Marcos St&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Austin&amp;#34;,&amp;#34;zip&amp;#34;:73344},&amp;#34;shipdate&amp;#34;:&amp;#34;2020-11-05&amp;#34;},
            {&amp;#34;shipid&amp;#34;:2,&amp;#34;address&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;100 main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:91001},&amp;#34;shipdate&amp;#34;:&amp;#34;2020-11-06&amp;#34;}]
   99149 |       139 | [{&amp;#34;shipid&amp;#34;:3,&amp;#34;address&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;100 main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:91001},&amp;#34;shipdate&amp;#34;:&amp;#34;2020-11-06&amp;#34;}]
   99162 |       139 | [{&amp;#34;shipid&amp;#34;:4,&amp;#34;address&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;100 main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:91001},&amp;#34;shipdate&amp;#34;:&amp;#34;2020-11-04&amp;#34;},
            {&amp;#34;shipid&amp;#34;:5,&amp;#34;address&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;100 Main St Apt 4A&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:91001},&amp;#34;shipdate&amp;#34;:&amp;#34;2020-11-11&amp;#34;}]
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can use array indexing and ROW field selection together in queries:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT orderid, shipments[0].shipdate AS ship1, shipments[1].shipdate AS ship2 FROM orders;
 orderid |   ship1    |   ship2
---------+------------+------------
   99123 | 2020-11-05 | 2020-11-06
   99149 | 2020-11-06 |
   99162 | 2020-11-04 | 2020-11-11
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This example selects specific array indices. To access all entries, use &lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/explode/#&#34;&gt;EXPLODE&lt;/a&gt;. To search or filter elements, see &lt;a href=&#34;#Searchin&#34;&gt;Searching and Filtering&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Some data formats have a map type, which is a set of key/value pairs. OpenText™ Analytics Database does not directly support querying maps, but you can define a map column as an array of structs and query that. In the following example, the &lt;code&gt;prods&lt;/code&gt; column in the data is a map:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE EXTERNAL TABLE orders
 (orderkey INT,
  custkey INT,
  prods ARRAY[ROW(key VARCHAR(10), value DECIMAL(12,2))],
  orderdate DATE
 ) AS COPY FROM &amp;#39;...&amp;#39; PARQUET;

=&amp;gt; SELECT orderkey, prods FROM orders;
 orderkey |                                              prods
----------+--------------------------------------------------------------------------------------------------
    19626 | [{&amp;#34;key&amp;#34;:&amp;#34;P68&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;49.99&amp;#34;},{&amp;#34;key&amp;#34;:&amp;#34;P1262&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;192.59&amp;#34;},{&amp;#34;key&amp;#34;:&amp;#34;P101&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;137.49&amp;#34;}]
    25646 | [{&amp;#34;key&amp;#34;:&amp;#34;P997&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;91.39&amp;#34;},{&amp;#34;key&amp;#34;:&amp;#34;P101&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;147.49&amp;#34;},{&amp;#34;key&amp;#34;:&amp;#34;P31&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;29.99&amp;#34;}]
    25647 | [{&amp;#34;key&amp;#34;:&amp;#34;P12&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;8.99&amp;#34;}]
    19743 | [{&amp;#34;key&amp;#34;:&amp;#34;P68&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;49.99&amp;#34;},{&amp;#34;key&amp;#34;:&amp;#34;P101&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;137.49&amp;#34;}]
    19888 | [{&amp;#34;key&amp;#34;:&amp;#34;P1262&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;197.59&amp;#34;},{&amp;#34;key&amp;#34;:&amp;#34;P101&amp;#34;,&amp;#34;value&amp;#34;:&amp;#34;142.49&amp;#34;}]
(5 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You cannot use complex columns in &lt;a href=&#34;../../../en/sql-reference/statements/create-statements/create-table/&#34;&gt;CREATE TABLE AS SELECT&lt;/a&gt; (CTAS). This restriction applies for the entire column or for field selection within it.&lt;/p&gt;
&lt;h2 id=&#34;ordering-and-grouping&#34;&gt;Ordering and grouping&lt;/h2&gt;
&lt;p&gt;You can use &lt;a href=&#34;../../../en/sql-reference/language-elements/operators/comparison-operators/#&#34;&gt;Comparison operators&lt;/a&gt; with collections of scalar values. Null collections are ordered last. Otherwise, collections are compared element by element until there is a mismatch, and then they are ordered based on the non-matching elements. If all elements are equal up to the length of the shorter one, then the shorter one is ordered first.&lt;/p&gt;
&lt;p&gt;You can use collections in the &lt;span class=&#34;sql&#34;&gt;ORDER BY&lt;/span&gt; and &lt;span class=&#34;sql&#34;&gt;GROUP BY&lt;/span&gt; clauses of queries. The following example shows ordering query results by an array column:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM employees
   ORDER BY grant_values;
 id | department |          grants          |  grant_values
----+------------+--------------------------+----------------
 36 | Astronomy  | [&amp;#34;US-7376&amp;#34;,&amp;#34;DARPA-1567&amp;#34;] | [5000,4000]
 36 | Physics    | [&amp;#34;US-7376&amp;#34;,&amp;#34;DARPA-1567&amp;#34;] | [10000,25000]
 33 | Physics    | [&amp;#34;US-7376&amp;#34;]              | [30000]
 42 | Physics    | [&amp;#34;US-7376&amp;#34;,&amp;#34;DARPA-1567&amp;#34;] | [65000,135000]
(4 rows)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The following example queries the same table using &lt;span class=&#34;sql&#34;&gt;GROUP BY&lt;/span&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT department, grants, SUM(apply_sum(grant_values))
   FROM employees
   GROUP BY grants, department;
 department |          grants          |  SUM
------------+--------------------------+--------
 Physics    | [&amp;#34;US-7376&amp;#34;,&amp;#34;DARPA-1567&amp;#34;] | 235000
 Astronomy  | [&amp;#34;US-7376&amp;#34;,&amp;#34;DARPA-1567&amp;#34;] |   9000
 Physics    | [&amp;#34;US-7376&amp;#34;]              |  30000
(3 rows)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;See the &amp;quot;Functions and Operators&amp;quot; section on the &lt;a href=&#34;../../../en/sql-reference/data-types/complex-types/array/#&#34;&gt;ARRAY&lt;/a&gt; reference page for information on how the database orders collections. (The same information is also on the &lt;a href=&#34;../../../en/sql-reference/data-types/complex-types/set/#&#34;&gt;SET&lt;/a&gt; reference page.)&lt;/p&gt;
&lt;h2 id=&#34;null-semantics&#34;&gt;Null semantics&lt;/h2&gt;
&lt;p&gt;Null semantics for collections are consistent with normal columns in most regards. See &lt;a href=&#34;../../../en/data-analysis/query-optimization/analytic-functions/null-sort-order/#&#34;&gt;NULL sort order&lt;/a&gt; for more information on null-handling.&lt;/p&gt;
&lt;p&gt;The null-safe equality operator (&amp;lt;=&amp;gt;) behaves differently from equality (=) when the collection is null rather than empty. Comparing a collection to NULL strictly returns null:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT ARRAY[1,3] = NULL;
?column?
----------

(1 row)

=&amp;gt; SELECT ARRAY[1,3] &amp;lt;=&amp;gt; NULL;
 ?column?
----------
 f
(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the following example, the grants column in the table is null for employee 99:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT grants = NULL FROM employees WHERE id=99;
 ?column?
----------

(1 row)

=&amp;gt; SELECT grants &amp;lt;=&amp;gt; NULL FROM employees WHERE id=99;
 ?column?
----------
 t
(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Empty collections are not null and behave as expected:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT ARRAY[]::ARRAY[INT] = ARRAY[]::ARRAY[INT];
 ?column?
----------
 t
(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Collections are compared element by element. If a comparison depends on a null element, the result is unknown (null), not false. For example, &lt;code&gt;ARRAY[1,2,null]=ARRAY[1,2,null]&lt;/code&gt; and &lt;code&gt;ARRAY[1,2,null]=ARRAY[1,2,3]&lt;/code&gt; both return null, but &lt;code&gt;ARRAY[1,2,null]=ARRAY[1,4,null]&lt;/code&gt; returns false because the second elements do not match.&lt;/p&gt;

&lt;p&gt;Out-of-bound indexes into collections return NULL:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT prodkey[2] FROM orders LIMIT 4;
prodkey
---------

&amp;#34;EH-1247&amp;#34;
&amp;#34;MH-2401&amp;#34;

(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The results of the query return NULL for two out of four rows, the first and the fourth, because the specified index is greater than the size of those arrays.&lt;/p&gt;
&lt;h2 id=&#34;casting&#34;&gt;Casting&lt;/h2&gt;
&lt;p&gt;When the data type of an expression value is unambiguous, it is implicitly coerced to match the expected data type. However, there can be ambiguity about the data type of an expression. Write an explicit cast to avoid the default:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT APPLY_SUM(ARRAY[&amp;#39;1&amp;#39;,&amp;#39;2&amp;#39;,&amp;#39;3&amp;#39;]);
ERROR 5595:  Invalid argument type VarcharArray1D in function apply_sum

=&amp;gt; SELECT APPLY_SUM(ARRAY[&amp;#39;1&amp;#39;,&amp;#39;2&amp;#39;,&amp;#39;3&amp;#39;]::ARRAY[INT]);
 apply_sum
-----------
         6
(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can cast arrays or sets of one scalar type to arrays or sets of other (compatible) types, following the same rules as for casting scalar values. Casting a collection casts each element of that collection. Casting an array to a set also removes any duplicates.&lt;/p&gt;
&lt;p&gt;You can cast arrays (but not sets) with elements that are arrays or structs (or combinations):&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT shipments::ARRAY[ROW(id INT,addr ROW(VARCHAR,VARCHAR,INT),shipped DATE)]
FROM orders;
                  shipments
---------------------------------------------------------------------------
 [{&amp;#34;id&amp;#34;:1,&amp;#34;addr&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;911 San Marcos St&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Austin&amp;#34;,&amp;#34;zip&amp;#34;:73344},&amp;#34;shipped&amp;#34;:&amp;#34;2020-11-05&amp;#34;},
  {&amp;#34;id&amp;#34;:2,&amp;#34;addr&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;100 main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:91001},&amp;#34;shipped&amp;#34;:&amp;#34;2020-11-06&amp;#34;}]
 [{&amp;#34;id&amp;#34;:3,&amp;#34;addr&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;100 main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:91001},&amp;#34;shipped&amp;#34;:&amp;#34;2020-11-06&amp;#34;}]
 [{&amp;#34;id&amp;#34;:4,&amp;#34;addr&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;100 main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:91001},&amp;#34;shipped&amp;#34;:&amp;#34;2020-11-04&amp;#34;},
  {&amp;#34;id&amp;#34;:5,&amp;#34;addr&amp;#34;:{&amp;#34;street&amp;#34;:&amp;#34;100 Main St Apt 4A&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:91001},&amp;#34;shipped&amp;#34;:&amp;#34;2020-11-11&amp;#34;}]
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can change the bound of an array or set by casting. When casting to a bounded native array, inputs that are too long are truncated. When casting to a multi-dimensional array, if the new bounds are too small for the data the cast fails:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT ARRAY[1,2,3]::ARRAY[VARCHAR,2];
   array
-----------
 [&amp;#34;1&amp;#34;,&amp;#34;2&amp;#34;]
(1 row)

=&amp;gt; SELECT ARRAY[ARRAY[1,2,3],ARRAY[4,5,6]]::ARRAY[ARRAY[VARCHAR,2],2];
ERROR 9227:  Output array isn&amp;#39;t big enough
DETAIL:  Type limit is 4 elements, but value has 6 elements
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you cast to a bounded multi-dimensional array, you must specify the bounds at all levels.&lt;/p&gt;
&lt;p&gt;An array or set with a single null element must be explicitly cast because no type can be inferred.&lt;/p&gt;
&lt;p&gt;See &lt;a href=&#34;../../../en/sql-reference/data-types/data-type-coercion/#&#34;&gt;Data type coercion&lt;/a&gt; for more information on casting for data types.&lt;/p&gt;
&lt;h2 id=&#34;exploding-and-imploding-array-columns&#34;&gt;Exploding and imploding array columns&lt;/h2&gt;
&lt;p&gt;To simplify access to elements, you can use the &lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/explode/#&#34;&gt;EXPLODE&lt;/a&gt; and &lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/unnest/#&#34;&gt;UNNEST&lt;/a&gt; functions. These functions take one or more array columns from a table and expand them, producing one row per element. You can use EXPLODE and UNNEST when you need to perform aggregate operations across all elements of all arrays. You can also use EXPLODE when you need to operate on individual elements. See &lt;a href=&#34;#Manipula&#34;&gt;Manipulating Elements&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;EXPLODE and UNNEST differ in their output:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;EXPLODE returns two columns for each array, one for the element index and one for the value at that position. If the function explodes a single array, these columns are named &lt;code&gt;position&lt;/code&gt; and &lt;code&gt;value&lt;/code&gt; by default. If the function explodes two or more arrays, the columns for each array are named &lt;code&gt;pos_&lt;/code&gt;&lt;em&gt;&lt;code&gt;column-name&lt;/code&gt;&lt;/em&gt; and &lt;code&gt;val_&lt;/code&gt;&lt;em&gt;&lt;code&gt;column-name&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;UNNEST returns only the values. For a single array, the output column is named &lt;code&gt;value&lt;/code&gt;. For multiple arrays, each output column is named &lt;code&gt;val_&lt;/code&gt;&lt;em&gt;&lt;code&gt;column-name&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;EXPLODE and UNNEST also differ in their inputs. UNNEST accepts only array arguments and expands all of them. EXPLODE can accept other arguments and passes them through, expanding only as many arrays as requested (default 1).&lt;/p&gt;
&lt;p&gt;Consider an orders table with the following contents:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT orderkey, custkey, prodkey, orderprices, email_addrs
   FROM orders LIMIT 5;
  orderkey  | custkey |                    prodkey                    |            orderprices            |                                                  email_addrs
------------+---------+-----------------------------------------------+-----------------------------------+----------------------------------------------------------------------------------------------------------------
 113-341987 |  342799 | [&amp;#34;MG-7190 &amp;#34;,&amp;#34;VA-4028 &amp;#34;,&amp;#34;EH-1247 &amp;#34;,&amp;#34;MS-7018 &amp;#34;] | [&amp;#34;60.00&amp;#34;,&amp;#34;67.00&amp;#34;,&amp;#34;22.00&amp;#34;,&amp;#34;14.99&amp;#34;] | [&amp;#34;bob@example,com&amp;#34;,&amp;#34;robert.jones@example.com&amp;#34;]
 111-952000 |  342845 | [&amp;#34;ID-2586 &amp;#34;,&amp;#34;IC-9010 &amp;#34;,&amp;#34;MH-2401 &amp;#34;,&amp;#34;JC-1905 &amp;#34;] | [&amp;#34;22.00&amp;#34;,&amp;#34;35.00&amp;#34;,null,&amp;#34;12.00&amp;#34;]    | [&amp;#34;br92@cs.example.edu&amp;#34;]
 111-345634 |  342536 | [&amp;#34;RS-0731 &amp;#34;,&amp;#34;SJ-2021 &amp;#34;]                       | [&amp;#34;50.00&amp;#34;,null]                    | [null]
 113-965086 |  342176 | [&amp;#34;GW-1808 &amp;#34;]                                  | [&amp;#34;108.00&amp;#34;]                        | [&amp;#34;joe.smith@example.com&amp;#34;]
 111-335121 |  342321 | [&amp;#34;TF-3556 &amp;#34;]                                  | [&amp;#34;50.00&amp;#34;]                         | [&amp;#34;789123@example-isp.com&amp;#34;,&amp;#34;alexjohnson@example.com&amp;#34;,&amp;#34;monica@eng.example.com&amp;#34;,&amp;#34;sara@johnson.example.name&amp;#34;,null]
(5 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following query explodes the order prices for a single customer. The other two columns are passed through and are repeated for each returned row:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT EXPLODE(orderprices, custkey, email_addrs
                  USING PARAMETERS skip_partitioning=true)
            AS (position, orderprices, custkey, email_addrs)
   FROM orders WHERE custkey=&amp;#39;342845&amp;#39; ORDER BY orderprices;
 position | orderprices | custkey |         email_addrs
----------+-------------+---------+------------------------------
        2 |             |  342845 | [&amp;#34;br92@cs.example.edu&amp;#34;,null]
        3 |       12.00 |  342845 | [&amp;#34;br92@cs.example.edu&amp;#34;,null]
        0 |       22.00 |  342845 | [&amp;#34;br92@cs.example.edu&amp;#34;,null]
        1 |       35.00 |  342845 | [&amp;#34;br92@cs.example.edu&amp;#34;,null]
(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The previous example uses the &lt;code&gt;skip_partitioning&lt;/code&gt; parameter. Instead of setting it for each call to EXPLODE, you can set it as a session parameter. EXPLODE is part of the ComplexTypesLib UDx library. The following example returns the same results:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; ALTER SESSION SET UDPARAMETER FOR ComplexTypesLib skip_partitioning=true;

=&amp;gt; SELECT EXPLODE(orderprices, custkey, email_addrs)
            AS (position, orderprices, custkey, email_addrs)
   FROM orders WHERE custkey=&amp;#39;342845&amp;#39; ORDER BY orderprices;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can explode more than one column by specifying the &lt;code&gt;explode_count&lt;/code&gt; parameter:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT EXPLODE(orderkey, prodkey, orderprices
                  USING PARAMETERS explode_count=2, skip_partitioning=true)
          AS (orderkey,pk_idx,pk_val,ord_idx,ord_val)
   FROM orders
   WHERE orderkey=&amp;#39;113-341987&amp;#39;;
  orderkey  | pk_idx |  pk_val  | ord_idx | ord_val
------------+--------+----------+---------+---------
 113-341987 |      0 | MG-7190  |       0 |   60.00
 113-341987 |      0 | MG-7190  |       1 |   67.00
 113-341987 |      0 | MG-7190  |       2 |   22.00
 113-341987 |      0 | MG-7190  |       3 |   14.99
 113-341987 |      1 | VA-4028  |       0 |   60.00
 113-341987 |      1 | VA-4028  |       1 |   67.00
 113-341987 |      1 | VA-4028  |       2 |   22.00
 113-341987 |      1 | VA-4028  |       3 |   14.99
 113-341987 |      2 | EH-1247  |       0 |   60.00
 113-341987 |      2 | EH-1247  |       1 |   67.00
 113-341987 |      2 | EH-1247  |       2 |   22.00
 113-341987 |      2 | EH-1247  |       3 |   14.99
 113-341987 |      3 | MS-7018  |       0 |   60.00
 113-341987 |      3 | MS-7018  |       1 |   67.00
 113-341987 |      3 | MS-7018  |       2 |   22.00
 113-341987 |      3 | MS-7018  |       3 |   14.99
(16 rows)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you do not need the element positions, you can use UNNEST:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT orderkey, UNNEST(prodkey, orderprices)
   FROM orders WHERE orderkey=&amp;#39;113-341987&amp;#39;;
  orderkey  | val_prodkey | val_orderprices
------------+-------------+-----------------
 113-341987 | MG-7190     |           60.00
 113-341987 | MG-7190     |           67.00
 113-341987 | MG-7190     |           22.00
 113-341987 | MG-7190     |           14.99
 113-341987 | VA-4028     |           60.00
 113-341987 | VA-4028     |           67.00
 113-341987 | VA-4028     |           22.00
 113-341987 | VA-4028     |           14.99
 113-341987 | EH-1247     |           60.00
 113-341987 | EH-1247     |           67.00
 113-341987 | EH-1247     |           22.00
 113-341987 | EH-1247     |           14.99
 113-341987 | MS-7018     |           60.00
 113-341987 | MS-7018     |           67.00
 113-341987 | MS-7018     |           22.00
 113-341987 | MS-7018     |           14.99
(16 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following example uses a multi-dimensional array:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT name, pingtimes FROM network_tests;
 name |                       pingtimes
------+-------------------------------------------------------
 eng1 | [[24.24,25.27,27.16,24.97],[23.97,25.01,28.12,29.5]]
 eng2 | [[27.12,27.91,28.11,26.95],[29.01,28.99,30.11,31.56]]
 qa1  | [[23.15,25.11,24.63,23.91],[22.85,22.86,23.91,31.52]]
(3 rows)

=&amp;gt; SELECT EXPLODE(name, pingtimes USING PARAMETERS explode_count=1) OVER()
   FROM network_tests;
 name | position |           value
------+----------+---------------------------
 eng1 |        0 | [24.24,25.27,27.16,24.97]
 eng1 |        1 | [23.97,25.01,28.12,29.5]
 eng2 |        0 | [27.12,27.91,28.11,26.95]
 eng2 |        1 | [29.01,28.99,30.11,31.56]
 qa1  |        0 | [23.15,25.11,24.63,23.91]
 qa1  |        1 | [22.85,22.86,23.91,31.52]
(6 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can rewrite the previous query as follows to produce the same results:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT name, EXPLODE(pingtimes USING PARAMETERS skip_partitioning=true)
   FROM network_tests;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/implode/#&#34;&gt;IMPLODE&lt;/a&gt; function is the inverse of EXPLODE and UNNEST: it takes a column and produces an array containing the column&#39;s values. You can use WITHIN GROUP ORDER BY to control the order of elements in the imploded array. Combined with GROUP BY, IMPLODE can be used to reverse an EXPLODE operation.&lt;/p&gt;
&lt;p&gt;If the output array would be too large for the column, IMPLODE returns an error. To avoid this, you can set the &lt;code&gt;allow_truncate&lt;/code&gt; parameter to omit some elements from the results. Truncation never applies to individual elements; for example, the function does not shorten strings.&lt;/p&gt;
&lt;p&gt;&lt;a name=&#34;Searchin&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;searching-and-filtering&#34;&gt;Searching and filtering&lt;/h2&gt;
&lt;p&gt;You can search array elements without having to first explode the array using the following functions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/contains/#&#34;&gt;CONTAINS&lt;/a&gt;: tests whether an array contains an element&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/array-find/#&#34;&gt;ARRAY_FIND&lt;/a&gt;: returns the position of the first matching element&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;../../../en/sql-reference/functions/data-type-specific-functions/collection-functions/filter/#&#34;&gt;FILTER&lt;/a&gt;: returns an array containing only matching elements from an input array&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can use CONTAINS and ARRAY_FIND to search for specific elements:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT CONTAINS(email, &amp;#39;frank@example.com&amp;#39;) FROM people;
 CONTAINS
----------
 f
 t
 f
 f
(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Suppose, instead of finding a particular address, you want to find all of the people who use an &lt;code&gt;example.com&lt;/code&gt; email address. Instead of specifying a literal value, you can supply a &lt;a href=&#34;../../../en/sql-reference/language-elements/lambda-functions/&#34;&gt;lambda function&lt;/a&gt; to test elements. A lambda function has the following syntax:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&lt;span class=&#34;code-variable&#34;&gt;argument&lt;/span&gt; -&amp;gt; &lt;span class=&#34;code-variable&#34;&gt;expression&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The lambda function takes the place of the second argument:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT CONTAINS(email, e -&amp;gt; REGEXP_LIKE(e,&amp;#39;example.com&amp;#39;,&amp;#39;i&amp;#39;)) FROM people;
 CONTAINS
----------
 f
 t
 f
 t
(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The FILTER function tests array elements, like ARRAY_FIND and CONTAINS, but then returns an array containing only the elements that match the filter:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT name, email FROM people;
      name      |                      email
----------------+-------------------------------------------------
 Elaine Jackson | [&amp;#34;ejackson@somewhere.org&amp;#34;,&amp;#34;elaine@jackson.com&amp;#34;]
 Frank Adams    | [&amp;#34;frank@example.com&amp;#34;]
 Lee Jones      | [&amp;#34;lee.jones@somewhere.org&amp;#34;]
 M Smith        | [&amp;#34;msmith@EXAMPLE.COM&amp;#34;,&amp;#34;ms@MSMITH.COM&amp;#34;]
(4 rows)

=&amp;gt; SELECT name, FILTER(email, e -&amp;gt; NOT REGEXP_LIKE(e,&amp;#39;example.com&amp;#39;,&amp;#39;i&amp;#39;)) AS &amp;#39;real_email&amp;#39;
   FROM people;
      name      |                   real_email
----------------+-------------------------------------------------
 Elaine Jackson | [&amp;#34;ejackson@somewhere.org&amp;#34;,&amp;#34;elaine@jackson.com&amp;#34;]
 Frank Adams    | []
 Lee Jones      | [&amp;#34;lee.jones@somewhere.org&amp;#34;]
 M Smith        | [&amp;#34;ms@MSMITH.COM&amp;#34;]
(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To filter out entire rows without real email addresses, test the array length after applying the filter:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT name, FILTER(email, e -&amp;gt; NOT REGEXP_LIKE(e,&amp;#39;example.com&amp;#39;,&amp;#39;i&amp;#39;)) AS &amp;#39;real_email&amp;#39;
   FROM people
   WHERE ARRAY_LENGTH(real_email) &amp;gt; 0;
      name      |                   real_email
----------------+-------------------------------------------------
 Elaine Jackson | [&amp;#34;ejackson@somewhere.org&amp;#34;,&amp;#34;elaine@jackson.com&amp;#34;]
 Lee Jones      | [&amp;#34;lee.jones@somewhere.org&amp;#34;]
 M Smith        | [&amp;#34;ms@MSMITH.COM&amp;#34;]
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The lambda function has an optional second argument, which is the element index. For an example that uses the index argument, see &lt;a href=&#34;../../../en/sql-reference/language-elements/lambda-functions/#&#34;&gt;Lambda functions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a name=&#34;Manipula&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;manipulating-elements&#34;&gt;Manipulating elements&lt;/h2&gt;
&lt;p&gt;You can filter array elements using the FILTER function as explained in &lt;a href=&#34;#Searchin&#34;&gt;Searching and Filtering&lt;/a&gt;. Filtering does not allow for operations on the filtered elements. For this case, you can use FILTER, EXPLODE, and IMPLODE together.&lt;/p&gt;
&lt;p&gt;Consider a table of people, where each row has a person&#39;s name and an array of email addresses, some invalid:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM people;
 id |      name      |                      email
----+----------------+-------------------------------------------------
 56 | Elaine Jackson | [&amp;#34;ejackson@somewhere.org&amp;#34;,&amp;#34;elaine@jackson.com&amp;#34;]
 61 | Frank Adams    | [&amp;#34;frank@example.com&amp;#34;]
 87 | Lee Jones      | [&amp;#34;lee.jones@somewhere.org&amp;#34;]
 91 | M Smith        | [&amp;#34;msmith@EXAMPLE.COM&amp;#34;,&amp;#34;ms@MSMITH.COM&amp;#34;]
(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Email addresses are case-insensitive but VARCHAR values are not. The following example filters out invalid email addresses and normalizes the remaining ones by converting them to lowercase. The order of operations for each row is:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Filter each array to remove addresses using &lt;code&gt;example.com&lt;/code&gt;, partitioning by name.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explode the filtered array.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Convert each element to lowercase.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Implode the lowercase elements, grouping by name.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; WITH exploded AS
(SELECT EXPLODE(FILTER(email, e -&amp;gt; NOT REGEXP_LIKE(e, &amp;#39;example.com&amp;#39;, &amp;#39;i&amp;#39;)), name)
        OVER (PARTITION BEST) AS (pos, addr, name)
        FROM people)
SELECT name, IMPLODE(LOWER(addr)) AS email
FROM exploded GROUP BY name;
      name      |                      email
----------------+-------------------------------------------------
 Elaine Jackson | [&amp;#34;ejackson@somewhere.org&amp;#34;,&amp;#34;elaine@jackson.com&amp;#34;]
 Lee Jones      | [&amp;#34;lee.jones@somewhere.org&amp;#34;]
 M Smith        | [&amp;#34;ms@msmith.com&amp;#34;]
(3 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because the second row in the original table did not have any remaining email addresses after the filter step, there was nothing to partition by. Therefore, the row does not appear in the results at all.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Rows (structs)</title>
      <link>/en/data-analysis/queries/rows-structs/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/rows-structs/</guid>
      <description>
        
        
        &lt;p&gt;Tables can include columns of the &lt;a href=&#34;../../../en/sql-reference/data-types/complex-types/row/#&#34;&gt;ROW&lt;/a&gt; data type. A ROW, sometimes called a struct, is a set of typed property-value pairs.&lt;/p&gt;
&lt;p&gt;Consider a table of customers with columns for name, address, and an ID. The address is a ROW with fields for the elements of an address (street, city, and postal code). As shown in this example, ROW values are returned in &lt;a href=&#34;https://www.w3schools.com/js/js_json_arrays.asp&#34;&gt;JSON format&lt;/a&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT * FROM customers ORDER BY accountID;
        name        |                              address                               | accountID
--------------------+--------------------------------------------------------------------+-----------
 Missy Cooper       | {&amp;#34;street&amp;#34;:&amp;#34;911 San Marcos St&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Austin&amp;#34;,&amp;#34;zipcode&amp;#34;:73344}     |        17
 Sheldon Cooper     | {&amp;#34;street&amp;#34;:&amp;#34;100 Main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}  |       139
 Leonard Hofstadter | {&amp;#34;street&amp;#34;:&amp;#34;100 Main St Apt 4A&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}  |       142
 Leslie Winkle      | {&amp;#34;street&amp;#34;:&amp;#34;23 Fifth Ave Apt 8C&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001} |       198
 Raj Koothrappali   | {&amp;#34;street&amp;#34;:null,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}                  |       294
 Stuart Bloom       |                                                                    |       482
(6 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Most values are cast to UTF-8 strings, as shown for street and city here. Integers and booleans are cast to JSON Numerics and thus not quoted.&lt;/p&gt;
&lt;p&gt;Use dot notation (&lt;em&gt;&lt;code&gt;column&lt;/code&gt;&lt;/em&gt;.&lt;em&gt;&lt;code&gt;field&lt;/code&gt;&lt;/em&gt;) to access individual fields:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT address.city FROM customers;
   city
----------
 Pasadena
 Pasadena
 Pasadena
 Pasadena
 Austin

(6 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the following example, the contact information in the customers table has an email field, which is an array of addresses:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT name, contact.email FROM customers;
        name        |                    email
--------------------+---------------------------------------------
 Missy Cooper       | [&amp;#34;missy@mit.edu&amp;#34;,&amp;#34;mcooper@cern.gov&amp;#34;]
 Sheldon Cooper     | [&amp;#34;shelly@meemaw.name&amp;#34;,&amp;#34;cooper@caltech.edu&amp;#34;]
 Leonard Hofstadter | [&amp;#34;hofstadter@caltech.edu&amp;#34;]
 Leslie Winkle      | []
 Raj Koothrappali   | [&amp;#34;raj@available.com&amp;#34;]
 Stuart Bloom       |
(6 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can use ROW columns or specific fields to restrict queries, as in the following example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; SELECT address FROM customers WHERE address.city =&amp;#39;Pasadena&amp;#39;;
                              address
--------------------------------------------------------------------
 {&amp;#34;street&amp;#34;:&amp;#34;100 Main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}
 {&amp;#34;street&amp;#34;:&amp;#34;100 Main St Apt 4A&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}
 {&amp;#34;street&amp;#34;:&amp;#34;23 Fifth Ave Apt 8C&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}
 {&amp;#34;street&amp;#34;:null,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}
(4 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can use the ROW syntax to specify literal values, such as the address in the WHERE clause in the following example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;
=&amp;gt; SELECT name,address FROM customers
   WHERE address = ROW(&amp;#39;100 Main St Apt 4A&amp;#39;,&amp;#39;Pasadena&amp;#39;,91001);
        name        |                              address
--------------------+-------------------------------------------------------------------
 Leonard Hofstadter | {&amp;#34;street&amp;#34;:&amp;#34;100 Main St Apt 4A&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}
(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can join on field values as you would from any other column:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT accountID,department from customers JOIN employees
   ON customers.name=employees.personal.name;
 accountID | department
-----------+------------
       139 | Physics
       142 | Physics
       294 | Astronomy
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can join on full structs. The following example joins the addresses in the employees and customers tables:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT employees.personal.name,customers.accountID FROM employees
JOIN customers ON employees.personal.address=customers.address;
        name        | accountID
--------------------+-----------
 Sheldon Cooper     |       139
 Leonard Hofstadter |       142
(2 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can cast structs, optionally specifying new field names:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; SELECT contact::ROW(str VARCHAR, city VARCHAR, zip VARCHAR, email ARRAY[VARCHAR,
20]) FROM customers;
                                                     contact

--------------------------------------------------------------------------------
----------------------------------
 {&amp;#34;str&amp;#34;:&amp;#34;911 San Marcos St&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Austin&amp;#34;,&amp;#34;zip&amp;#34;:&amp;#34;73344&amp;#34;,&amp;#34;email&amp;#34;:[&amp;#34;missy@mit.ed
u&amp;#34;,&amp;#34;mcooper@cern.gov&amp;#34;]}
 {&amp;#34;str&amp;#34;:&amp;#34;100 Main St Apt 4B&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:&amp;#34;91001&amp;#34;,&amp;#34;email&amp;#34;:[&amp;#34;shelly@me
emaw.name&amp;#34;,&amp;#34;cooper@caltech.edu&amp;#34;]}
 {&amp;#34;str&amp;#34;:&amp;#34;100 Main St Apt 4A&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:&amp;#34;91001&amp;#34;,&amp;#34;email&amp;#34;:[&amp;#34;hofstadte
r@caltech.edu&amp;#34;]}
 {&amp;#34;str&amp;#34;:&amp;#34;23 Fifth Ave Apt 8C&amp;#34;,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:&amp;#34;91001&amp;#34;,&amp;#34;email&amp;#34;:[]}
 {&amp;#34;str&amp;#34;:null,&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zip&amp;#34;:&amp;#34;91001&amp;#34;,&amp;#34;email&amp;#34;:[&amp;#34;raj@available.com&amp;#34;]}

(6 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can use structs in views and in subqueries, as in the following example:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;=&amp;gt; CREATE VIEW neighbors (num_neighbors, area(city, zipcode))
AS SELECT count(*), ROW(address.city, address.zipcode)
FROM customers GROUP BY address.city, address.zipcode;
CREATE VIEW

=&amp;gt; SELECT employees.personal.name, neighbors.area FROM neighbors, employees
WHERE employees.personal.address.zipcode=neighbors.area.zipcode AND neighbors.nu
m_neighbors &amp;gt; 1;
        name        |                area
--------------------+-------------------------------------
 Sheldon Cooper     | {&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}
 Leonard Hofstadter | {&amp;#34;city&amp;#34;:&amp;#34;Pasadena&amp;#34;,&amp;#34;zipcode&amp;#34;:91001}
(2 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If a reference is ambiguous, the database prefers column names over field names.&lt;/p&gt;
&lt;p&gt;You can use many operators and predicates with ROW columns, including JOIN, GROUP BY, ORDER BY, IS [NOT] NULL, and comparison operations in nullable filters. Some operators do not logically apply to structured data and are not supported. See the &lt;a href=&#34;../../../en/sql-reference/data-types/complex-types/row/#&#34;&gt;ROW&lt;/a&gt; reference page for a complete list.&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Subqueries</title>
      <link>/en/data-analysis/queries/subqueries/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/subqueries/</guid>
      <description>
        
        
        &lt;p&gt;A subquery is a SELECT statement embedded within another SELECT statement. The embedded subquery is often referenced as the query&#39;s inner statement, while the containing query is typically referenced as the query&#39;s statement, or outer query block. A subquery returns data that the outer query uses as a condition to determine what data to retrieve. There is no limit to the number of nested subqueries you can create.&lt;/p&gt;
&lt;p&gt;Like any query, a subquery returns records from a table that might consist of a single column and record, a single column with multiple records, or multiple columns and records. Subqueries can be &lt;a href=&#34;../../../en/data-analysis/queries/subqueries/noncorrelated-and-correlated-subqueries/&#34;&gt;noncorrelated or correlated&lt;/a&gt;. You can also use them to &lt;a href=&#34;../../../en/data-analysis/queries/subqueries/subqueries-update-and-delete-statements/&#34;&gt;update or delete&lt;/a&gt; table records, based on values in other database tables.
&lt;/p&gt;

      </description>
    </item>
    
    <item>
      <title>Data-Analysis: Joins</title>
      <link>/en/data-analysis/queries/joins/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      
      <guid>/en/data-analysis/queries/joins/</guid>
      <description>
        
        
        &lt;p&gt;Queries can combine records from multiple tables, or multiple instances of the same table. A query that combines records from one or more tables is called a join. Joins are allowed in &lt;code&gt;SELECT&lt;/code&gt; statements and subqueries.&lt;/p&gt;
&lt;h2 id=&#34;supported-join-types&#34;&gt;Supported join types&lt;/h2&gt;
&lt;p&gt;OpenText™ Analytics Database supports the following join types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Inner (including natural, cross) joins&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Left, right, and full outer joins&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Optimizations for equality and range joins predicates&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nested loop joins are not supported.&lt;/p&gt;
&lt;h2 id=&#34;join-algorithms&#34;&gt;Join algorithms&lt;/h2&gt;
&lt;p&gt;The database query optimizer implements joins with either the hash join or merge join algorithm. For details, see &lt;a href=&#34;../../../en/data-analysis/query-optimization/join-queries/hash-joins-versus-merge-joins/#&#34;&gt;Hash joins versus merge joins&lt;/a&gt;.&lt;/p&gt;

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