<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://quant.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Tue, 13 Oct 2026 23:09:51 GMT</lastBuildDate><atom:link href="https://quant.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[BigQuery Arrays vs MySQL JSON: 
Generating sequences.]]></title><description><![CDATA[TL;DR
BigQuery features Arrays that are a powerful addition to standard SQL. In MySQL, JSON objects offer similar functionalities, but generating sequences requires some workarounds. MySQL's implementation of recursions offers even greater flexibilit...]]></description><link>https://quant.hashnode.dev/bigquery-arrays-vs-mysql-json-generating-sequences</link><guid isPermaLink="true">https://quant.hashnode.dev/bigquery-arrays-vs-mysql-json-generating-sequences</guid><category><![CDATA[SQL]]></category><category><![CDATA[Data Science]]></category><category><![CDATA[MySQL]]></category><dc:creator><![CDATA[Andreas Rhode]]></dc:creator><pubDate>Tue, 05 Apr 2022 02:22:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1649125769606/2DPDnWXCW.svg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-tldr">TL;DR</h3>
<p><strong>BigQuery</strong> features <a target="_blank" href="https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions">Arrays</a> that are a powerful addition to standard <strong>SQL</strong>. In <strong>MySQL</strong>, <a target="_blank" href="https://dev.mysql.com/doc/refman/8.0/en/json-creation-functions.html">JSON objects</a> offer similar functionalities, but generating sequences requires some workarounds. MySQL's implementation of recursions offers even greater flexibility. </p>
<h3 id="heading-bigquery-vs-mysql">BigQuery vs MySQL</h3>
<p>Cloud-based distributed data warehouses like BigQuery are all the rage these days, however, they often do not stand alone just containing static data sets. Data might first be generated within operational applications that are backed by systems like MySQL that allow for real-time data inserts and updates. Those operational data feeds are then usually shipped to the warehouse through connectors like <a target="_blank" href="www.fivetran.com">Fivetran</a>. In addition, emerging architecture like <a target="_blank" href="https://www.oracle.com/mysql/heatwave">Oracle heatwave</a> allows MySQL to take up compute loads that are traditionally placed within a warehouse.  </p>
<p>Operating in an environment of fast-moving and developing technologies, it becomes desirable to stay within common patterns and not overly rely on special features that one vendor offers but not the other. Thus the interest in comparing SQL on BigQuery and MySQL for similar tasks.</p>
<h3 id="heading-generate-a-sequence-of-numbers-n-123n">Generate a sequence of numbers n = 1,2,3,...,N</h3>
<p><a target="_blank" href="https://en.wikiquote.org/wiki/Leopold_Kronecker">Leopold Kronecker</a> once said, <em>"God made the integers, all the rest is the work of man"</em>. His quote is an attestation to the fundamental nature of the sequence of counting numbers. It seems more so surprising how cumbersome it is to generate such numbers using the <strong>SQL</strong> language within modern data systems.</p>
<p>Fortunately, Google's <a target="_blank" href="https://console.cloud.google.com/bigquery"><strong>BigQuery</strong></a> extension to standard SQL features the <strong>ARRAY</strong> data type coming to the rescue. Within BigQuery arrays can be specified as comma-separated lists.</p>
<p>Executing on the BigQuery console </p>
<pre><code><span class="hljs-string">select</span> [<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>] <span class="hljs-string">as</span> <span class="hljs-string">arr</span>
</code></pre><p>returns a single row that contains the array in the following form.</p>
<pre><code><span class="hljs-string">Row</span>    <span class="hljs-string">arr</span>    
 <span class="hljs-number">1</span>       <span class="hljs-number">1</span>    
         <span class="hljs-number">2</span>
         <span class="hljs-number">3</span>
</code></pre><p>What makes this powerful is that a sequence can be generated dynamically using the build-in <code>generate_array(start, end, stepsize)</code> function. 
Finally, <code>UNNEST()</code>  allows transforming array elements back into individual rows as shown</p>
<pre><code><span class="hljs-keyword">select</span> odd_number <span class="hljs-keyword">from</span> UNNEST(generate_array(<span class="hljs-number">1</span>,<span class="hljs-number">5</span>,<span class="hljs-number">2</span>)) <span class="hljs-keyword">as</span> odd_number
</code></pre><p>resulting now in a table where each row now contains a single number.</p>
<pre><code><span class="hljs-string">Row</span> <span class="hljs-string">odd_number</span>
<span class="hljs-number">1</span>     <span class="hljs-number">1</span>
<span class="hljs-number">2</span>     <span class="hljs-number">3</span>
<span class="hljs-number">3</span>     <span class="hljs-number">5</span>
</code></pre><p>Using this technique we can compute such fun problems as <em>to sum over all numbers between 1 and 100</em> </p>
<pre><code><span class="hljs-keyword">select</span> <span class="hljs-keyword">sum</span>(<span class="hljs-built_in">number</span>) <span class="hljs-keyword">as</span> total <span class="hljs-keyword">from</span> <span class="hljs-keyword">UNNEST</span>(generate_array(<span class="hljs-number">1</span>,<span class="hljs-number">100</span>,<span class="hljs-number">1</span>)) <span class="hljs-keyword">as</span> <span class="hljs-built_in">number</span>
</code></pre><p>which by the way <a target="_blank" href="https://en.wikipedia.org/wiki/Carl_Friedrich_Gauss">Johann Karl Friedrich Gauss</a> had figured out already as 50*101=5050 (without having to google it), <em>to estimate PI from a simulation of 1,000,000 samples</em></p>
<pre><code><span class="hljs-keyword">select</span> 
          <span class="hljs-number">4</span>*<span class="hljs-keyword">avg</span>(<span class="hljs-keyword">if</span>(<span class="hljs-keyword">pow</span>(<span class="hljs-keyword">rand</span>(),<span class="hljs-number">2</span>)+<span class="hljs-keyword">pow</span>(<span class="hljs-keyword">rand</span>(),<span class="hljs-number">2</span>)&lt;<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">0</span>)) <span class="hljs-keyword">as</span> <span class="hljs-keyword">pi</span>
<span class="hljs-keyword">from</span> 
           <span class="hljs-keyword">UNNEST</span>(generate_array(<span class="hljs-number">1</span>,<span class="hljs-number">1000000</span>,<span class="hljs-number">1</span>)) <span class="hljs-keyword">as</span> i
</code></pre><p>or <em>to approximate the value of PI from a series formula</em> according to <a target="_blank" href="https://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%93Plouffe_formula">Bailey-Borwein Plouffe</a>  </p>
<pre><code><span class="hljs-keyword">with</span> s <span class="hljs-keyword">as</span> 
(
  <span class="hljs-keyword">select</span>
   k,
   <span class="hljs-keyword">pow</span>(<span class="hljs-number">16</span>,-k)*
   (
    <span class="hljs-number">4</span>/(<span class="hljs-number">8</span>*k+<span class="hljs-number">1</span>)
    <span class="hljs-number">-2</span>/(<span class="hljs-number">8</span>*k+<span class="hljs-number">4</span>)
    <span class="hljs-number">-1</span>/(<span class="hljs-number">8</span>*k+<span class="hljs-number">5</span>)
    <span class="hljs-number">-1</span>/(<span class="hljs-number">8</span>*k+<span class="hljs-number">6</span>)
   ) <span class="hljs-keyword">as</span> n
<span class="hljs-keyword">from</span> <span class="hljs-keyword">UNNEST</span>(generate_array(<span class="hljs-number">0</span>,<span class="hljs-number">11</span>,<span class="hljs-number">1</span>)) <span class="hljs-keyword">as</span> k  
)
<span class="hljs-keyword">select</span> 
  k, 
  <span class="hljs-keyword">sum</span>(n) <span class="hljs-keyword">over</span>(<span class="hljs-keyword">order</span> <span class="hljs-keyword">by</span> k) <span class="hljs-keyword">as</span> bbp_pi, 
  <span class="hljs-keyword">acos</span>(<span class="hljs-number">-1</span>) <span class="hljs-keyword">as</span> <span class="hljs-keyword">pi</span>, 
  <span class="hljs-keyword">sum</span>(n) <span class="hljs-keyword">over</span>(<span class="hljs-keyword">order</span> <span class="hljs-keyword">by</span> k)-<span class="hljs-keyword">acos</span>(<span class="hljs-number">-1</span>) <span class="hljs-keyword">as</span> <span class="hljs-keyword">error</span> 
<span class="hljs-keyword">from</span> s
</code></pre><p>which converges pretty quick.</p>
<pre><code><span class="hljs-attribute">Row</span>    k    bbp_pi             pi                error    
<span class="hljs-attribute">1</span>      <span class="hljs-number">0</span>    <span class="hljs-number">3</span>.<span class="hljs-number">1333333333333333</span> <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">0</span>.<span class="hljs-number">008259320256459812</span>
<span class="hljs-attribute">2</span>      <span class="hljs-number">1</span>    <span class="hljs-number">3</span>.<span class="hljs-number">1414224664224664</span> <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">1</span>.<span class="hljs-number">7018716732675188</span>E-<span class="hljs-number">4</span>
<span class="hljs-attribute">3</span>      <span class="hljs-number">2</span>    <span class="hljs-number">3</span>.<span class="hljs-number">141587390346581</span>  <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">5</span>.<span class="hljs-number">26324321192817</span>E-<span class="hljs-number">6</span>    
<span class="hljs-attribute">4</span>      <span class="hljs-number">3</span>    <span class="hljs-number">3</span>.<span class="hljs-number">141592457567435</span>  <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">1</span>.<span class="hljs-number">9602235790117106</span>E-<span class="hljs-number">7</span>
<span class="hljs-attribute">5</span>      <span class="hljs-number">4</span>    <span class="hljs-number">3</span>.<span class="hljs-number">141592645460336</span>  <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">8</span>.<span class="hljs-number">12945710748636</span>E-<span class="hljs-number">9</span>
<span class="hljs-attribute">6</span>      <span class="hljs-number">5</span>    <span class="hljs-number">3</span>.<span class="hljs-number">1415926532280873</span> <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">3</span>.<span class="hljs-number">6170577644156765</span>E-<span class="hljs-number">10</span>    
<span class="hljs-attribute">7</span>      <span class="hljs-number">6</span>    <span class="hljs-number">3</span>.<span class="hljs-number">1415926535728804</span> <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">1</span>.<span class="hljs-number">6912693467929785</span>E-<span class="hljs-number">11</span>
<span class="hljs-attribute">8</span>      <span class="hljs-number">7</span>    <span class="hljs-number">3</span>.<span class="hljs-number">1415926535889724</span> <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">8</span>.<span class="hljs-number">206768598029157</span>E-<span class="hljs-number">13</span>    
<span class="hljs-attribute">9</span>      <span class="hljs-number">8</span>    <span class="hljs-number">3</span>.<span class="hljs-number">141592653589752</span>  <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">4</span>.<span class="hljs-number">1300296516055823</span>E-<span class="hljs-number">14</span>    
<span class="hljs-attribute">10</span>     <span class="hljs-number">9</span>    <span class="hljs-number">3</span>.<span class="hljs-number">141592653589791</span>  <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">2</span>.<span class="hljs-number">220446049250313</span>E-<span class="hljs-number">15</span>
<span class="hljs-attribute">11</span>    <span class="hljs-number">10</span>    <span class="hljs-number">3</span>.<span class="hljs-number">1415926535897927</span> <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span> -<span class="hljs-number">4</span>.<span class="hljs-number">440892098500626</span>E-<span class="hljs-number">16</span>
<span class="hljs-attribute">12</span>    <span class="hljs-number">11</span>    <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span>  <span class="hljs-number">3</span>.<span class="hljs-number">141592653589793</span>  <span class="hljs-number">0</span>.<span class="hljs-number">0</span>
</code></pre><h3 id="heading-histograms-counting-zip-codes">Histograms, counting zip-codes</h3>
<p>Being able to generate sequences of numbers comes in handy when one needs an independent data axis to report on. Let's consider the example of census data that is reported as population counts by zip code. Counts are provided in the table by cohorts as well as rolled up into subtotals. To retrieve the respective overall total we fetch the row with the maximum value for each zip code. We want to generate a report of the number of zip codes that fall within a total population range bucket. </p>
<p>Below we first generate buckets of size 10,000 and then count the number of zip code regions within the selected population size.</p>
<pre><code><span class="hljs-keyword">with</span> total_population <span class="hljs-keyword">as</span>
(
<span class="hljs-keyword">select</span> 
            zipcode,
            <span class="hljs-keyword">max</span>(population) <span class="hljs-keyword">as</span> population  <span class="hljs-comment">--  the row with the largest amount has the aggregate total</span>
<span class="hljs-keyword">from</span> 
            bigquery-<span class="hljs-keyword">public</span>-data.census_bureau_usa.population_by_zip_2010
<span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> 
            zipcode
)

<span class="hljs-keyword">select</span> 
            population_bucket, 
            <span class="hljs-keyword">count</span>(zipcode) <span class="hljs-keyword">as</span> number_of_zipcodes 
            <span class="hljs-keyword">FROM</span>  <span class="hljs-keyword">UNNEST</span>(generate_array(<span class="hljs-number">10000</span>,<span class="hljs-number">150000</span>, <span class="hljs-number">10000</span>) ) <span class="hljs-keyword">as</span> population_bucket 
            <span class="hljs-keyword">left</span> <span class="hljs-keyword">join</span> total_population
<span class="hljs-keyword">on</span> 
            population <span class="hljs-keyword">between</span> population_bucket<span class="hljs-number">-10000</span> <span class="hljs-keyword">and</span> population_bucket
<span class="hljs-keyword">group</span> <span class="hljs-keyword">by</span> 
            population_bucket
<span class="hljs-keyword">order</span> <span class="hljs-keyword">by</span> 
            population_bucket
</code></pre><p>Generating the buckets independently of the population table ensures that a bucket is reported even in the case there are no corresponding zip code regions in the table, as shown in the rows corresponding to buckets 13,000 and above.</p>
<pre><code><span class="hljs-string">Row</span>    <span class="hljs-string">population_bucket</span>    <span class="hljs-string">number_of_zipcodes</span>    
<span class="hljs-number">1</span>      <span class="hljs-number">10000</span>                      <span class="hljs-number">23520</span>
<span class="hljs-number">2</span>      <span class="hljs-number">20000</span>                      <span class="hljs-number">3779</span>
<span class="hljs-number">3</span>      <span class="hljs-number">30000</span>                      <span class="hljs-number">2621</span>
<span class="hljs-number">4</span>      <span class="hljs-number">40000</span>                      <span class="hljs-number">1664</span>
<span class="hljs-number">5</span>      <span class="hljs-number">50000</span>                      <span class="hljs-number">831</span>
<span class="hljs-number">6</span>      <span class="hljs-number">60000</span>                      <span class="hljs-number">399</span>
<span class="hljs-number">7</span>      <span class="hljs-number">70000</span>                      <span class="hljs-number">167</span>
<span class="hljs-number">8</span>      <span class="hljs-number">80000</span>                      <span class="hljs-number">75</span>
<span class="hljs-number">9</span>      <span class="hljs-number">90000</span>                      <span class="hljs-number">34</span>
<span class="hljs-number">10</span>    <span class="hljs-number">100000</span>                      <span class="hljs-number">22</span>
<span class="hljs-number">11</span>    <span class="hljs-number">110000</span>                      <span class="hljs-number">8</span>
<span class="hljs-number">12</span>    <span class="hljs-number">120000</span>                      <span class="hljs-number">2</span>
<span class="hljs-number">13</span>    <span class="hljs-number">130000</span>                      <span class="hljs-number">0</span>
<span class="hljs-number">14</span>    <span class="hljs-number">140000</span>                      <span class="hljs-number">0</span>
<span class="hljs-number">15</span>    <span class="hljs-number">150000</span>                      <span class="hljs-number">0</span>
</code></pre><h2 id="heading-mysql-80-hello-jsonarray">MYSQL 8.0: Hello JSON_ARRAY</h2>
<p>To experiment with MySQL we use version 8.0 on https://dbfiddle.uk . MySQL does not feature arrays as directly as BigQuery, however, as a sort of work-around, it does support JSON types that can represent arrays. </p>
<pre><code><span class="hljs-attribute">select</span> JSON_ARRAY(<span class="hljs-number">1</span>,<span class="hljs-number">2</span>,<span class="hljs-number">3</span>);
</code></pre><p>yields</p>
<pre><code>[<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>]
</code></pre><p>So far so good, unfortunately, there is no generate_json_array function. 
To go further on our quest to generate a sequence of numbers with arrays, we need to resort to workarounds, such as first generating a carefully formatted string that then can be cast into a JSON object. </p>
<p>The following first step looks promising</p>
<pre><code><span class="hljs-keyword">select</span> cast(concat("[1",repeat(",1",<span class="hljs-number">3</span><span class="hljs-number">-1</span>),"]") <span class="hljs-keyword">as</span> <span class="hljs-type">JSON</span>)
</code></pre><p>which gives a JSON array of repeated unit elements</p>
<pre><code>[<span class="hljs-number">1</span>,<span class="hljs-number">1</span>,<span class="hljs-number">1</span>]
</code></pre><p>Next, we transform this back to a table of sequential numbers using the <a target="_blank" href="https://dev.mysql.com/doc/refman/8.0/en/json-table-functions.html">JSON_TABLE</a> function. Similar to UNNEST in the BigQuery case, JSON_TABLE extracts each element of the JSON array into rows of a single column. </p>
<pre><code><span class="hljs-keyword">select</span> <span class="hljs-built_in">number</span> <span class="hljs-keyword">from</span>
JSON_TABLE
( 
       <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">concat</span>(<span class="hljs-string">"[1"</span>, <span class="hljs-keyword">repeat</span>(<span class="hljs-string">",1"</span>, <span class="hljs-number">3</span><span class="hljs-number">-1</span>), <span class="hljs-string">"]"</span>) <span class="hljs-keyword">as</span> <span class="hljs-keyword">JSON</span>),
       <span class="hljs-string">"$[*]"</span>    <span class="hljs-comment">-- selects all elements in the JSON array</span>
       <span class="hljs-keyword">COLUMNS</span>(<span class="hljs-built_in">number</span> <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">ORDINALITY</span>)    <span class="hljs-comment">-- enumerates rows</span>
) numbers;
</code></pre><p>Rather than taking the actual value of each element, we export out its ordinal position instead, which generates the desired sequence of increasing numbers. </p>
<pre><code><span class="hljs-string">number</span>
<span class="hljs-number">1</span>
<span class="hljs-number">2</span>
<span class="hljs-number">3</span>
</code></pre><p>With these methods at hand, the MySQL version of the Gauss summation becomes</p>
<pre><code><span class="hljs-keyword">select</span> <span class="hljs-keyword">sum</span>(<span class="hljs-built_in">number</span>) <span class="hljs-keyword">from</span>
JSON_TABLE
( 
   <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">concat</span>(<span class="hljs-string">"[1"</span>,<span class="hljs-keyword">repeat</span>(<span class="hljs-string">",1"</span>,<span class="hljs-number">100</span><span class="hljs-number">-1</span>),<span class="hljs-string">"]"</span>) <span class="hljs-keyword">as</span> <span class="hljs-keyword">JSON</span>),
   <span class="hljs-string">"$[*]"</span>
   <span class="hljs-keyword">COLUMNS</span>(<span class="hljs-built_in">number</span> <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">ORDINALITY</span>)
) numbers;
</code></pre><p>and the formula for generating PI translates to</p>
<pre><code><span class="hljs-keyword">with</span> s <span class="hljs-keyword">as</span> 
(
 <span class="hljs-keyword">select</span>
   k,
   <span class="hljs-keyword">pow</span>(<span class="hljs-number">16</span>,-k+<span class="hljs-number">1</span>)*
   (
     <span class="hljs-number">4</span>/(<span class="hljs-number">8</span>*k<span class="hljs-number">-7</span>) 
    <span class="hljs-number">-2</span>/(<span class="hljs-number">8</span>*k<span class="hljs-number">-4</span>) 
    <span class="hljs-number">-1</span>/(<span class="hljs-number">8</span>*k<span class="hljs-number">-3</span>) 
    <span class="hljs-number">-1</span>/(<span class="hljs-number">8</span>*k<span class="hljs-number">-2</span>) 
   ) <span class="hljs-keyword">as</span> n
<span class="hljs-keyword">FROM</span>
JSON_TABLE
( 
           <span class="hljs-keyword">cast</span>(<span class="hljs-keyword">concat</span>(<span class="hljs-string">"[1"</span>,<span class="hljs-keyword">repeat</span>(<span class="hljs-string">",1"</span>,<span class="hljs-number">11</span><span class="hljs-number">-1</span>),<span class="hljs-string">"]"</span>) <span class="hljs-keyword">as</span> <span class="hljs-keyword">JSON</span>),
           <span class="hljs-string">"$[*]"</span>
           <span class="hljs-keyword">COLUMNS</span>(k <span class="hljs-keyword">FOR</span> <span class="hljs-keyword">ORDINALITY</span>)
) <span class="hljs-keyword">as</span> numbers

)
<span class="hljs-keyword">select</span> 
          k,
          <span class="hljs-keyword">sum</span>(n) <span class="hljs-keyword">over</span>(<span class="hljs-keyword">order</span> <span class="hljs-keyword">by</span> k) <span class="hljs-keyword">as</span> bbp_pi,  
          <span class="hljs-keyword">acos</span>(<span class="hljs-number">-1</span>) <span class="hljs-keyword">as</span> <span class="hljs-keyword">pi</span>, 
          <span class="hljs-keyword">sum</span>(n) <span class="hljs-keyword">over</span>(<span class="hljs-keyword">order</span> <span class="hljs-keyword">by</span> k)-<span class="hljs-keyword">acos</span>(<span class="hljs-number">-1</span>) <span class="hljs-keyword">as</span> <span class="hljs-keyword">error</span> 
<span class="hljs-keyword">from</span> s
</code></pre><p>where we adjusted terms for the fact that k starts with 1 instead of 0.</p>
<h2 id="heading-recursions-lets-do-the-time-warp-again">Recursions: let's do the time warp again</h2>
<p>It's astounding, MySQL has another trick up its sleeve by supporting <a target="_blank" href="https://dev.mysql.com/doc/refman/8.0/en/with.html#common-table-expressions-recursive">recursions</a>. It's just a jump to the left and Gauss gets his summation of the first 100 numbers as</p>
<pre><code><span class="hljs-keyword">set</span> @@cte_max_recursion_depth = <span class="hljs-number">100</span>;
<span class="hljs-keyword">with</span> <span class="hljs-keyword">recursive</span> numbers(n) <span class="hljs-keyword">as</span>
(
  <span class="hljs-keyword">select</span> <span class="hljs-number">1</span>
  <span class="hljs-keyword">union</span>
  <span class="hljs-keyword">select</span> n+<span class="hljs-number">1</span> <span class="hljs-keyword">from</span> numbers <span class="hljs-keyword">where</span> n&lt;<span class="hljs-number">100</span>
)
<span class="hljs-keyword">select</span> <span class="hljs-keyword">sum</span>(n) <span class="hljs-keyword">from</span> numbers;
</code></pre><p>where we set cte_max_recursion_depth to the required capacity.  That's fantastic, so why bother with JSON_ARRAYs when recursions are so powerful? One limitation is that recursion depth max_sp_recursion_depth might be restricted by your particular system for user-defined functions. The other aspect that makes arrays interesting is the ability to store more complex structures than just individual numbers and strings. That shall be a topic for another time.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1649125869177/PGO5Q6T85.svg" alt="foot_prints.svg" /></p>
]]></content:encoded></item></channel></rss>