<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Gerald Venzl 🚀</title>
    <description>The latest articles on Forem by Gerald Venzl 🚀 (@gvenzl).</description>
    <link>https://forem.com/gvenzl</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F62263%2F2a16cf94-6ea3-43d3-b01c-5132c357eba3.jpg</url>
      <title>Forem: Gerald Venzl 🚀</title>
      <link>https://forem.com/gvenzl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/gvenzl"/>
    <language>en</language>
    <item>
      <title>How to write an anonymous PL/SQL function and use it in your SQL statement</title>
      <dc:creator>Gerald Venzl 🚀</dc:creator>
      <pubDate>Mon, 20 Mar 2023 15:00:00 +0000</pubDate>
      <link>https://forem.com/gvenzl/how-to-write-an-anonymous-plsql-function-and-use-it-in-your-sql-statement-4ahj</link>
      <guid>https://forem.com/gvenzl/how-to-write-an-anonymous-plsql-function-and-use-it-in-your-sql-statement-4ahj</guid>
      <description>&lt;p&gt;Have you ever encountered a situation when you were in the middle of writing a SQL query and thought, “if only I could write a quick PL/SQL function for this, it would make this quick and easy?” But, unfortunately, you don’t have any privileges to create any functions in the schema. Luckily, since Oracle Database 12c, there is an answer for you.&lt;/p&gt;

&lt;p&gt;With the release of Oracle Database 12.1.0.1 in 2013, Oracle introduced the capability of writing anonymous PL/SQL declarations as part of a SQL query. This is done with the &lt;code&gt;WITH&lt;/code&gt; clause also referred to as &lt;strong&gt;Common Table Expression&lt;/strong&gt; clause or &lt;strong&gt;CTE&lt;/strong&gt;, which can now contain said anonymous PL/SQL declarations.&lt;/p&gt;

&lt;p&gt;Let’s imagine for a second that you have a table &lt;code&gt;products&lt;/code&gt; containing information about various sellers’ products. This could look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;id&lt;/span&gt;     &lt;span class="n"&gt;NUMBER&lt;/span&gt;         &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;name&lt;/span&gt;   &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;url&lt;/span&gt;    &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'AirPods Pro (2nd gen)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'https://www.apple.com/shop/product/MQD83AM/A/airpods-pro'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SanDisk - Ultra 512GB USB 3.0'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'https://www.bestbuy.com/site/sandisk-ultra-512gb-usb-3-0-flash-drive-black/6422265.p'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You would like to write a query that provides you, say, the product name, the domain where each product is sold and the URL. But you want to ensure that the first letter of the name and the domain name is always capitalized. Sure, you can do that in pure SQL, but you are comfortable with PL/SQL, and such functions are written quickly:&lt;/p&gt;

&lt;h4&gt;
  
  
  get_domain_name function
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;get_domain_name&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;p_url&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;p_sub_domain&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'www.'&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;
&lt;span class="k"&gt;IS&lt;/span&gt;
  &lt;span class="n"&gt;v_begin_pos&lt;/span&gt; &lt;span class="n"&gt;BINARY_INTEGER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;v_length&lt;/span&gt;    &lt;span class="n"&gt;BINARY_INTEGER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
  &lt;span class="n"&gt;v_begin_pos&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p_sub_domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;LENGTH&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_sub_domain&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;v_length&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_begin_pos&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_begin_pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  capitalize function
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;capitalize&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_string&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;
&lt;span class="k"&gt;IS&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
  &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;UPPER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this new feature, you can simply wrap both these functions into the &lt;code&gt;WITH&lt;/code&gt; clause and reuse them within your SQL block, even multiple times:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt;
  &lt;span class="c1"&gt;-- Function to capitalize input string&lt;/span&gt;
  &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;capitalize&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;p_string&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;
  &lt;span class="k"&gt;IS&lt;/span&gt;
  &lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;UPPER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="c1"&gt;-- Function to retrieve the domain name from a URL&lt;/span&gt;
  &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;get_domain_name&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;p_url&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;p_sub_domain&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'www.'&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;
  &lt;span class="k"&gt;IS&lt;/span&gt;
    &lt;span class="n"&gt;v_begin_pos&lt;/span&gt; &lt;span class="n"&gt;BINARY_INTEGER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;v_length&lt;/span&gt;    &lt;span class="n"&gt;BINARY_INTEGER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="n"&gt;v_begin_pos&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p_sub_domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;LENGTH&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_sub_domain&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;v_length&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_begin_pos&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_begin_pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="c1"&gt;-- SQL statement&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_domain_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;domain_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
  &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To the database, this is just another &lt;code&gt;SELECT&lt;/code&gt; statement with a common table expression. You do not need any write privileges on the schema for the user you are connected with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SQL&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;WITH&lt;/span&gt;
  &lt;span class="mi"&gt;2&lt;/span&gt;    &lt;span class="c1"&gt;-- Function to capitalize input string&lt;/span&gt;
  &lt;span class="mi"&gt;3&lt;/span&gt;    &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;capitalize&lt;/span&gt;
  &lt;span class="mi"&gt;4&lt;/span&gt;      &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="mi"&gt;5&lt;/span&gt;        &lt;span class="n"&gt;p_string&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;
  &lt;span class="mi"&gt;6&lt;/span&gt;      &lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="mi"&gt;7&lt;/span&gt;      &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;
  &lt;span class="mi"&gt;8&lt;/span&gt;    &lt;span class="k"&gt;IS&lt;/span&gt;
  &lt;span class="mi"&gt;9&lt;/span&gt;    &lt;span class="k"&gt;BEGIN&lt;/span&gt;
 &lt;span class="mi"&gt;10&lt;/span&gt;      &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;UPPER&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
 &lt;span class="mi"&gt;11&lt;/span&gt;    &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="mi"&gt;12&lt;/span&gt;    &lt;span class="c1"&gt;-- Function to retrieve the domain name from a URL&lt;/span&gt;
 &lt;span class="mi"&gt;13&lt;/span&gt;    &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;get_domain_name&lt;/span&gt;
 &lt;span class="mi"&gt;14&lt;/span&gt;      &lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="mi"&gt;15&lt;/span&gt;        &lt;span class="n"&gt;p_url&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="mi"&gt;16&lt;/span&gt;        &lt;span class="n"&gt;p_sub_domain&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="s1"&gt;'www.'&lt;/span&gt;
 &lt;span class="mi"&gt;17&lt;/span&gt;      &lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="mi"&gt;18&lt;/span&gt;      &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;VARCHAR2&lt;/span&gt;
 &lt;span class="mi"&gt;19&lt;/span&gt;    &lt;span class="k"&gt;IS&lt;/span&gt;
 &lt;span class="mi"&gt;20&lt;/span&gt;      &lt;span class="n"&gt;v_begin_pos&lt;/span&gt; &lt;span class="n"&gt;BINARY_INTEGER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="mi"&gt;21&lt;/span&gt;      &lt;span class="n"&gt;v_length&lt;/span&gt;    &lt;span class="n"&gt;BINARY_INTEGER&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="mi"&gt;22&lt;/span&gt;    &lt;span class="k"&gt;BEGIN&lt;/span&gt;
 &lt;span class="mi"&gt;23&lt;/span&gt;      &lt;span class="n"&gt;v_begin_pos&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;p_sub_domain&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="k"&gt;LENGTH&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_sub_domain&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="mi"&gt;24&lt;/span&gt;      &lt;span class="n"&gt;v_length&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;INSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_begin_pos&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;'.'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="mi"&gt;25&lt;/span&gt;      &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_begin_pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v_length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
 &lt;span class="mi"&gt;26&lt;/span&gt;    &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="mi"&gt;27&lt;/span&gt;  &lt;span class="c1"&gt;-- SQL statement&lt;/span&gt;
 &lt;span class="mi"&gt;28&lt;/span&gt;  &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;get_domain_name&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;domain_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
 &lt;span class="mi"&gt;29&lt;/span&gt;    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;

&lt;span class="n"&gt;NAME&lt;/span&gt;                             &lt;span class="n"&gt;DOMAIN_NAME&lt;/span&gt;    &lt;span class="n"&gt;URL&lt;/span&gt;
&lt;span class="n"&gt;________________________________&lt;/span&gt; &lt;span class="n"&gt;______________&lt;/span&gt; &lt;span class="n"&gt;_______________________________________________________________________________________&lt;/span&gt;
&lt;span class="n"&gt;AirPods&lt;/span&gt; &lt;span class="n"&gt;Pro&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;nd&lt;/span&gt; &lt;span class="n"&gt;gen&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;            &lt;span class="n"&gt;Apple&lt;/span&gt;          &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;apple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;shop&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;MQD83AM&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;A&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;airpods&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;pro&lt;/span&gt;
&lt;span class="n"&gt;SanDisk&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Ultra&lt;/span&gt; &lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="n"&gt;GB&lt;/span&gt; &lt;span class="n"&gt;USB&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;    &lt;span class="n"&gt;Bestbuy&lt;/span&gt;        &lt;span class="n"&gt;https&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;//&lt;/span&gt;&lt;span class="n"&gt;www&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bestbuy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;com&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;site&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sandisk&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;ultra&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;512&lt;/span&gt;&lt;span class="n"&gt;gb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;usb&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;flash&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;drive&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;black&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;6422265&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>sql</category>
      <category>oracle</category>
      <category>database</category>
      <category>plsql</category>
    </item>
    <item>
      <title>Percentage calculations using SQL Window Functions</title>
      <dc:creator>Gerald Venzl 🚀</dc:creator>
      <pubDate>Tue, 06 Dec 2022 14:00:00 +0000</pubDate>
      <link>https://forem.com/gvenzl/percentage-calculations-using-sql-window-functions-4nkm</link>
      <guid>https://forem.com/gvenzl/percentage-calculations-using-sql-window-functions-4nkm</guid>
      <description>&lt;p&gt;Sometimes you have the requirement to calculate percentages on some values of your data. There are multiple ways of doing it, of course, but often people are not aware that you do not have to calculate these percentages in the application itself or via a SQL statement that queries the same table multiple times to first calculate the denominator and then calculate the actual percentage. Instead, you can use &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Window_function_%28SQL%29" rel="noopener noreferrer"&gt;SQL window functions&lt;/a&gt; to run a variety of complex calculations over different groups of data in a single pass!&lt;/strong&gt; Window functions were &lt;strong&gt;introduced in the SQL:2003 standard back in 2003&lt;/strong&gt; and although the SQL standard calls these &lt;em&gt;Window Functions&lt;/em&gt;, Oracle Database has them documented as &lt;em&gt;&lt;a href="https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/Analytic-Functions.html" rel="noopener noreferrer"&gt;Analytic Functions&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let’s take a look.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example Data
&lt;/h2&gt;

&lt;p&gt;First, we need to have some data that we can run queries against. Let’s use movies and calculate the percentages of the actors’ earnings – fictional, of course. 🙂&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;movie_name&lt;/span&gt;   &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;actor_name&lt;/span&gt;   &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;earnings&lt;/span&gt;     &lt;span class="n"&gt;NUMBER&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Thor: Love and Thunder'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Chris Hemsworth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Thor: Love and Thunder'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Natalie Portman'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Thor: Love and Thunder'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Christian Bale'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;1000000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Minions: The Rise of Gru'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Steve Carell'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;500000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
   &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Minions: The Rise of Gru'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Pierre Coffin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;COMMIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Percentage Total Earnings per Actor
&lt;/h2&gt;

&lt;p&gt;Back in the days before window functions were available, and unfortunately still too often today, you will find queries with the two-step approach that will read the same table twice, first to get the denominator and second to run the actual computation of the percentage using the denominator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actor_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;sums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
         &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt;
     &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;sums&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;MOVIE_NAME&lt;/span&gt;               &lt;span class="n"&gt;ACTOR_NAME&lt;/span&gt;      &lt;span class="n"&gt;PERCENT&lt;/span&gt;
&lt;span class="c1"&gt;------------------------ --------------- -------&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Chris&lt;/span&gt; &lt;span class="n"&gt;Hemsworth&lt;/span&gt;   &lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Natalie&lt;/span&gt; &lt;span class="n"&gt;Portman&lt;/span&gt;   &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Christian&lt;/span&gt; &lt;span class="n"&gt;Bale&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Steve&lt;/span&gt; &lt;span class="n"&gt;Carell&lt;/span&gt;       &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;81&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Pierre&lt;/span&gt; &lt;span class="n"&gt;Coffin&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this produces the correct result, it has an unnecessary second query on the same table. With window functions, however – and once again, they have been around in some databases for more 20 years now and added to the SQL standard in 2003 – you can calculate the denominator of the percentage in a single go, no need to read the table twice:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actor_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;earnings&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;MOVIE_NAME&lt;/span&gt;               &lt;span class="n"&gt;ACTOR_NAME&lt;/span&gt;      &lt;span class="n"&gt;PERCENT&lt;/span&gt;
&lt;span class="c1"&gt;------------------------ --------------- -------&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Chris&lt;/span&gt; &lt;span class="n"&gt;Hemsworth&lt;/span&gt;   &lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Natalie&lt;/span&gt; &lt;span class="n"&gt;Portman&lt;/span&gt;   &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Christian&lt;/span&gt; &lt;span class="n"&gt;Bale&lt;/span&gt;    &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Steve&lt;/span&gt; &lt;span class="n"&gt;Carell&lt;/span&gt;       &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;81&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Pierre&lt;/span&gt; &lt;span class="n"&gt;Coffin&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The window function in the above statement is the &lt;code&gt;SUM(earnings) OVER ()&lt;/code&gt; part. Concise, isn’t it?&lt;/p&gt;

&lt;h2&gt;
  
  
  Percentage of Earnings per Movie
&lt;/h2&gt;

&lt;p&gt;Of course, calculating the percentage of earnings for all movies is interesting but perhaps more interesting is to know who the highest-paid actor in a given movie is. Prior to window functions, you may have written a statement like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;actor_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;
      &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt;
        &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;movie_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;movie_name&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;MOVIE_NAME&lt;/span&gt;               &lt;span class="n"&gt;ACTOR_NAME&lt;/span&gt;      &lt;span class="n"&gt;PERCENT&lt;/span&gt;
&lt;span class="c1"&gt;------------------------ --------------- -------&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Steve&lt;/span&gt; &lt;span class="n"&gt;Carell&lt;/span&gt;      &lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Pierre&lt;/span&gt; &lt;span class="n"&gt;Coffin&lt;/span&gt;     &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Chris&lt;/span&gt; &lt;span class="n"&gt;Hemsworth&lt;/span&gt;    &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Natalie&lt;/span&gt; &lt;span class="n"&gt;Portman&lt;/span&gt;      &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Christian&lt;/span&gt; &lt;span class="n"&gt;Bale&lt;/span&gt;     &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The benefit of using window functions is that we can reuse the same query from before and just change the way how we partition the data for our analysis. The previous statement had a window function with a trailing &lt;code&gt;OVER()&lt;/code&gt; clause. That &lt;code&gt;OVER()&lt;/code&gt; clause is there to tell the window function, among other things, what part of the retrieved data to apply the calculation on. Window functions use values from one or multiple rows to return a value for each row. This contrasts with aggregate functions, which return a single value for multiple rows. In short, window functions always have an &lt;code&gt;OVER()&lt;/code&gt; clause while any function without an &lt;code&gt;OVER()&lt;/code&gt; clause is not a window function, but rather an aggregate or single-row (scalar) function.&lt;/p&gt;

&lt;p&gt;To calculate the percentages &lt;strong&gt;&lt;em&gt;per movie&lt;/em&gt;&lt;/strong&gt;, all you have to do is to tell the window function to look at the data on a per-movie basis. In other words, partition the retrieved data by the movie_name and apply the calculation for each partition or window of data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actor_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;earnings&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                          &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;percent&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;MOVIE_NAME&lt;/span&gt;               &lt;span class="n"&gt;ACTOR_NAME&lt;/span&gt;      &lt;span class="n"&gt;PERCENT&lt;/span&gt;
&lt;span class="c1"&gt;------------------------ --------------- -------&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Steve&lt;/span&gt; &lt;span class="n"&gt;Carell&lt;/span&gt;      &lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Pierre&lt;/span&gt; &lt;span class="n"&gt;Coffin&lt;/span&gt;     &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Chris&lt;/span&gt; &lt;span class="n"&gt;Hemsworth&lt;/span&gt;    &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Natalie&lt;/span&gt; &lt;span class="n"&gt;Portman&lt;/span&gt;      &lt;span class="mi"&gt;25&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Christian&lt;/span&gt; &lt;span class="n"&gt;Bale&lt;/span&gt;     &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pay attention to the (now in a separate line for further illustration purposes) &lt;code&gt;OVER (PARTITION BY movie_name)&lt;/code&gt; clause. That’s all that needed to change to execute the percentage calculations per movie.&lt;/p&gt;

&lt;h2&gt;
  
  
  Percentage of Earnings per Movie and Total Earnings
&lt;/h2&gt;

&lt;p&gt;The cool thing about window functions is that you can use multiple window functions in one SQL statement! So, for example, instead of executing the two statements above, you can just run one single query and retrieve both calculations in one go:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actor_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;earnings&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                          &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;ptc_movie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;earnings&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                          &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;ptc_total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptc_movie&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;MOVIE_NAME&lt;/span&gt;               &lt;span class="n"&gt;ACTOR_NAME&lt;/span&gt;      &lt;span class="n"&gt;PTC_MOVIE&lt;/span&gt; &lt;span class="n"&gt;PTC_TOTAL&lt;/span&gt;
&lt;span class="c1"&gt;------------------------ --------------- --------- ---------&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Steve&lt;/span&gt; &lt;span class="n"&gt;Carell&lt;/span&gt;        &lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;      &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;81&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Pierre&lt;/span&gt; &lt;span class="n"&gt;Coffin&lt;/span&gt;       &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Chris&lt;/span&gt; &lt;span class="n"&gt;Hemsworth&lt;/span&gt;      &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;     &lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Natalie&lt;/span&gt; &lt;span class="n"&gt;Portman&lt;/span&gt;        &lt;span class="mi"&gt;25&lt;/span&gt;     &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Christian&lt;/span&gt; &lt;span class="n"&gt;Bale&lt;/span&gt;       &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;     &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This result provides some interesting insights right away. Here you can quickly see that although Steve Carell got the most money from his movie, it is just a tiny fraction of what others have made with their movies. We know this already, of course, because of the queries earlier on, but here you have the numbers next to each other, making it much more apparent. And, of course, we didn’t need to read the table twice to get the per movie and total earnings percentages either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Many functions to choose from
&lt;/h2&gt;

&lt;p&gt;Just like with aggregate functions, there are many different window functions available, so always check out the documentation! It just happens to be that Oracle Database has a &lt;code&gt;RATIO_TO_REPORT&lt;/code&gt; function &lt;em&gt;that computes the ratio of a value to the sum of a set of values&lt;/em&gt;. In other words, there already is a window function to calculate the percentages. So the above query can be further simplified to the following, saving you from having to do the division manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actor_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;RATIO_TO_REPORT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;ptc_movie&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;RATIO_TO_REPORT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;earnings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;ptc_total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;movie_earnings&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;movie_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ptc_movie&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;MOVIE_NAME&lt;/span&gt;               &lt;span class="n"&gt;ACTOR_NAME&lt;/span&gt;      &lt;span class="n"&gt;PTC_MOVIE&lt;/span&gt; &lt;span class="n"&gt;PTC_TOTAL&lt;/span&gt;
&lt;span class="c1"&gt;------------------------ --------------- --------- ---------&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Steve&lt;/span&gt; &lt;span class="n"&gt;Carell&lt;/span&gt;        &lt;span class="mi"&gt;83&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;33&lt;/span&gt;      &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;81&lt;/span&gt;
&lt;span class="n"&gt;Minions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;Rise&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="n"&gt;Gru&lt;/span&gt; &lt;span class="n"&gt;Pierre&lt;/span&gt; &lt;span class="n"&gt;Coffin&lt;/span&gt;       &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;67&lt;/span&gt;      &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Chris&lt;/span&gt; &lt;span class="n"&gt;Hemsworth&lt;/span&gt;      &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;     &lt;span class="mi"&gt;58&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;14&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Natalie&lt;/span&gt; &lt;span class="n"&gt;Portman&lt;/span&gt;        &lt;span class="mi"&gt;25&lt;/span&gt;     &lt;span class="mi"&gt;23&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;26&lt;/span&gt;
&lt;span class="n"&gt;Thor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Love&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;Thunder&lt;/span&gt;   &lt;span class="n"&gt;Christian&lt;/span&gt; &lt;span class="n"&gt;Bale&lt;/span&gt;       &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;     &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;63&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Window functions, or analytical functions as Oracle calls them, are a powerful way to execute complex calculations over multiple “windows” in a query result.&lt;/p&gt;

&lt;p&gt;They are much more compact than other methods and only need to read the data once instead of multiple times, giving you a performance boost for running complex calculations on large data sets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Window functions should be in the toolbox of any developer who regularly writes SQL!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you want to learn more about window functions, check out the &lt;strong&gt;free &lt;a href="https://devgym.oracle.com/pls/apex/f?p=10001:29:12240084544217:::29:P29_CLASS_ID:601&amp;amp;cs=1KNldxb3a_ljbgHkzxWDMKaVn4w1JpvePpwv5a_-pfpK8g2CB1vji4eQNRAIDq6QI9KGi8oBrsFwx7ZoMNOxnPw" rel="noopener noreferrer"&gt;Analytic SQL for Developers&lt;/a&gt;&lt;/strong&gt; course from Oracle!&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>5 ways to get an Oracle Database</title>
      <dc:creator>Gerald Venzl 🚀</dc:creator>
      <pubDate>Tue, 22 Sep 2020 01:17:25 +0000</pubDate>
      <link>https://forem.com/gvenzl/5-ways-to-get-an-oracle-database-2nl0</link>
      <guid>https://forem.com/gvenzl/5-ways-to-get-an-oracle-database-2nl0</guid>
      <description>&lt;p&gt;Do you want to get your hands on an Oracle Database but don't know how? Here are &lt;em&gt;5 ways to get you going&lt;/em&gt;:&lt;/p&gt;

&lt;h1&gt;
  
  
  LiveSQL
&lt;/h1&gt;

&lt;p&gt;Do you just want to type some awesome SQL and need a database to do so? Then &lt;a href="https://livesql.oracle.com/"&gt;LiveSQL.oracle.com&lt;/a&gt; is your friend. LiveSQL is a browser-based SQL scratchpad that not only allows you to pull off some SQL magic but also to save and share your scripts with others. It also comes with a comprehensive library of tutorials and samples. LiveSQL is the best place for anybody that is completely unfamiliar with Oracle Database and wants to get going.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F47bozawc6jth299m5p5n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F47bozawc6jth299m5p5n.png" alt="LiveSQL" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Docker/Container image
&lt;/h1&gt;

&lt;p&gt;If you want to have an Oracle Database on your machine instead, but don't want to worry about setup and configuration, the Oracle provided Docker images are a good choice. All you need is to install Docker, Podman or an equivalent on your machine (&lt;a href="https://docs.docker.com/docker-for-mac/"&gt;Mac&lt;/a&gt; or &lt;a href="https://docs.docker.com/docker-for-windows/"&gt;Windows&lt;/a&gt;) and pull the Oracle Database image from &lt;a href="https://container-registry.oracle.com/"&gt;Oracle's Container Registry&lt;/a&gt;. From then on, all you have to remember is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; oracle &lt;span class="nt"&gt;-p&lt;/span&gt; 1521:1521 container-registry.oracle.com/database/free:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker start oracle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvyrh9dximtjcliiqx859.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fvyrh9dximtjcliiqx859.gif" alt="Oracle Database in Docker" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Docker is great for running one or many instances and versions of an Oracle Database on your machine without having to know how to operate (start/stop/setup) them. What you end up with is still a full-fledged Oracle Database.&lt;/p&gt;

&lt;h1&gt;
  
  
  Vagrant box VM
&lt;/h1&gt;

&lt;p&gt;If you want to have an Oracle Database on your machine, but you prefer to run it inside a Virtual Machine, then the Oracle provided Vagrant scripts will do a great job. HashiCorp's &lt;a href="https://www.vagrantup.com/"&gt;Vagrant&lt;/a&gt; is a great tool to provision repeatable VM environments, including &lt;a href="https://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt; VMs. For this scenario, you will need to install &lt;a href="https://www.virtualbox.org/wiki/Downloads"&gt;Oracle's VirtualBox&lt;/a&gt; and &lt;a href="https://www.vagrantup.com/downloads.html"&gt;HashiCorp's Vagrant&lt;/a&gt; on your machine first. Once you have done that, provision a VM via the scripts from the &lt;a href="https://github.com/oracle/vagrant-boxes/tree/master/OracleDatabase"&gt;Oracle Vagrant Boxes GitHub repo&lt;/a&gt; and let Vagrant take care of the rest. All you have to remember is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnme4wo3e081fk0v82lda.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fnme4wo3e081fk0v82lda.gif" alt="Oracle Database with Vagrant" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Vagrant box is great if you want a scripted and repeatable way of creating a VirtualBox VM that contains an Oracle Database. You can also provision multiple VMs with different versions of the Oracle Database. The VM comes with port forwarding enabled by default, which means that you are able to connect any of your tools from your host directly, say SQL Developer for example, to the database inside the VM and treat the VM like a little embedded server.&lt;/p&gt;

&lt;h1&gt;
  
  
  Database App Dev VM
&lt;/h1&gt;

&lt;p&gt;If you like the VM approach but don't want or need the repeatable nature of Vagrant, then the &lt;a href="https://www.oracle.com/database/technologies/databaseappdev-vm.html"&gt;Oracle Database Application Development VM&lt;/a&gt; is the right choice for you. Simply download the .ova file, import it into VirtualBox, and start the VM. The VM will boot into a graphical Linux desktop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fid9lwu7emose6xah4aa0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fid9lwu7emose6xah4aa0.png" alt="Oracle Database App Dev VM" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Oracle Database App Dev VM comes with tools like SQL Developer and Oracle REST Data Services preinstalled, which makes it a great self-contained, one-stop-shop VM. It too has port forwarding enabled by default, in case you want to connect your tools from your host directly. Another bonus of the App Dev VM is that it also includes some hands-on labs that you can go through.&lt;/p&gt;

&lt;h1&gt;
  
  
  Always Free Oracle Autonomous Database
&lt;/h1&gt;

&lt;p&gt;If you want an Oracle Database but not on your laptop, then you should check out the &lt;a href="https://www.oracle.com/cloud/free/"&gt;Oracle Cloud Free Tier&lt;/a&gt; which includes an Always Free Oracle Autonomous Database. Once you have signed up for the free tier and provisioned your Always Free Autonomous Database, you can head over to SQL Developer Web and get going.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn2s8j1r4ulebvzffd2fk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn2s8j1r4ulebvzffd2fk.png" alt="Always Free Autonomous Database" width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Always Free Tier Oracle Autonomous Database is great if you want the latest and greatest what Oracle has to offer in terms of cloud databases. SQL Developer Web and APEX come out of the box and you can connect any other app or IDE from anywhere around the world, as long as it has access to the internet. And the best part, as long as you use the database, it stays with you forever!&lt;/p&gt;

&lt;p&gt;Now, what you are waiting for? Get yourself an Oracle Database!&lt;/p&gt;

</description>
      <category>oracle</category>
      <category>gettingstarted</category>
      <category>database</category>
    </item>
  </channel>
</rss>
