{"id":340,"date":"2023-06-18T19:55:04","date_gmt":"2023-06-18T18:55:04","guid":{"rendered":"https:\/\/zdebla.me\/?p=340"},"modified":"2023-06-18T19:55:04","modified_gmt":"2023-06-18T18:55:04","slug":"sql-to-tableau","status":"publish","type":"post","link":"https:\/\/zdebla.me\/index.php\/2023\/06\/18\/sql-to-tableau\/","title":{"rendered":"SQL to Tableau"},"content":{"rendered":"\n<p>The objective of this project is to showcase connecting Tableau (could be done with any BI software naturally) and thus reducing the size of the information that is extracted, which greatly improves the visualisation performance.<\/p>\n\n\n\n<p class=\"has-text-align-center has-vivid-cyan-blue-color has-text-color\"><strong>Database design (schema)<\/strong><\/p>\n\n\n\n<p>I first created a mock database in MS Access, with 2 tables:<\/p>\n\n\n\n<p><em><strong>flights <\/strong><\/em>&#8211; This one contains information extracted from the EUROSTAT database &#8211; the list of airport pairs for all flights from Germany. The extraction process is similar to the one described <a href=\"https:\/\/zdebla.me\/index.php\/2023\/06\/07\/airport-pairs-dataset-preparation\/\" data-type=\"post\" data-id=\"154\">in this article.<\/a><\/p>\n\n\n\n<p>I cleaned the data and kept only those for the years 2018, 2019 and 2020 and the following columns (airport of origin, destination country, destination airport, year, number of flights, number of passengers and number of seats available) :<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"345\" height=\"159\" src=\"https:\/\/zdebla.me\/wp-content\/uploads\/2023\/06\/obrazok-48.png\" alt=\"\" class=\"wp-image-341\" srcset=\"https:\/\/zdebla.me\/wp-content\/uploads\/2023\/06\/obrazok-48.png 345w, https:\/\/zdebla.me\/wp-content\/uploads\/2023\/06\/obrazok-48-300x138.png 300w\" sizes=\"auto, (max-width: 345px) 100vw, 345px\" \/><\/figure>\n\n\n\n<p>This table 2500 rows, representing data for the top airport pairs, each of the pairs would have at least one flight a day in average (356 per year).<\/p>\n\n\n\n<p><strong><em>delays<\/em><\/strong> &#8211; The data comes from the E<a href=\"https:\/\/ansperformance.eu\/data\/\">UROCONTROL&#8217;s Airport ATFM delay dataset<\/a>. I extrected the airports from Germany and kept the following columns (year, airport ICAO code, airport name, minutes of delay, number of flights):<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"350\" height=\"118\" src=\"https:\/\/zdebla.me\/wp-content\/uploads\/2023\/06\/obrazok-49.png\" alt=\"\" class=\"wp-image-342\" srcset=\"https:\/\/zdebla.me\/wp-content\/uploads\/2023\/06\/obrazok-49.png 350w, https:\/\/zdebla.me\/wp-content\/uploads\/2023\/06\/obrazok-49-300x101.png 300w\" sizes=\"auto, (max-width: 350px) 100vw, 350px\" \/><\/figure>\n\n\n\n<p>This tables has 484 rows.<\/p>\n\n\n\n<p class=\"has-text-align-center has-vivid-cyan-blue-color has-text-color\"><strong>The query<\/strong><\/p>\n\n\n\n<p> The objective of the visulisation was to aggregate the pairs of airports of origin with countries of destination, filtering out only the airports that had an average ATFM delay per flight higher than 0.90 min (average value for 2019 as per EUROCONTROL <em><a href=\"https:\/\/www.eurocontrol.int\/publication\/eurocontrol-standard-inputs-economic-analyses\">Standard Inputs for Economic Analyses<\/a><\/em>.<\/p>\n\n\n\n<p>To do this I wrote the following SQL query. The query combines both tables <strong>using the airport ICAO code and the year as a key.<\/strong><\/p>\n\n\n\n<p><em><strong>SELECT <\/strong>f.apt_ori, f.ctr_des, f.YEAR, SUM(f.CAF_PAS_DEP) AS number_flights, SUM(f.PAS_BRD_DEP) AS pax, SUM(f.ST_PAS_DEP) AS seats_available<\/em>, SUM(f.PAS_BRD_DEP)\/SUM(f.ST_PAS_DEP)*100 AS <em>load_factor_perc<\/em><br><strong>FROM <\/strong>flights AS f LEFT JOIN delays AS d ON (f.apt_ori = d.APT_ICAO) AND (f.YEAR = d.YEAR)<br><strong>WHERE <\/strong>f.ctr_des &lt;> &#8220;DE&#8221;<br><strong>GROUP BY <\/strong>f.apt_ori, f.ctr_des, f.YEAR<br><strong>HAVING <\/strong>SUM(d.delay_min\/d.arrivals_num) > 0.9<br><\/p>\n\n\n\n<p class=\"has-text-align-center has-vivid-cyan-blue-color has-text-color\"><strong>The result and the visulisation<\/strong><\/p>\n\n\n\n<p>The resulting query has 206 rows. In the next step, I could directly load the database into <em>Tableau<\/em> and use the query result for the following visualisation:<\/p>\n\n\n\n<div class='tableauPlaceholder' id='viz1687114450397' style='position: relative'><noscript><a href='#'><img alt='Dashboard 1 ' src='https:&#47;&#47;public.tableau.com&#47;static&#47;images&#47;de&#47;de_airports&#47;Dashboard1&#47;1_rss.png' style='border: none' \/><\/a><\/noscript><object class='tableauViz'  style='display:none;'><param name='host_url' value='https%3A%2F%2Fpublic.tableau.com%2F' \/> <param name='embed_code_version' value='3' \/> <param name='site_root' value='' \/><param name='name' value='de_airports&#47;Dashboard1' \/><param name='tabs' value='no' \/><param name='toolbar' value='yes' \/><param name='static_image' value='https:&#47;&#47;public.tableau.com&#47;static&#47;images&#47;de&#47;de_airports&#47;Dashboard1&#47;1.png' \/> <param name='animate_transition' value='yes' \/><param name='display_static_image' value='yes' \/><param name='display_spinner' value='yes' \/><param name='display_overlay' value='yes' \/><param name='display_count' value='yes' \/><param name='language' value='en-US' \/><\/object><\/div>                <script type='text\/javascript'>                    var divElement = document.getElementById('viz1687114450397');                    var vizElement = divElement.getElementsByTagName('object')[0];                    if ( divElement.offsetWidth > 860 ) { vizElement.style.width='650px';vizElement.style.height='887px';} else if ( divElement.offsetWidth > 500 ) { vizElement.style.width='650px';vizElement.style.height='887px';} else { vizElement.style.width='100%';vizElement.style.height='727px';}                     var scriptElement = document.createElement('script');                    scriptElement.src = 'https:\/\/public.tableau.com\/javascripts\/api\/viz_v1.js';                    vizElement.parentNode.insertBefore(scriptElement, vizElement);                <\/script>\n","protected":false},"excerpt":{"rendered":"<p>The objective of this project is to showcase connecting Tableau (could be done with any BI software naturally) and thus reducing the size of the information that is extracted, which greatly improves the visualisation performance. Database design (schema) I first created a mock database in MS Access, with 2 tables: flights &#8211; This one contains [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-340","post","type-post","status-publish","format-standard","hentry","category-projects"],"_links":{"self":[{"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/posts\/340","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/comments?post=340"}],"version-history":[{"count":1,"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/posts\/340\/revisions"}],"predecessor-version":[{"id":343,"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/posts\/340\/revisions\/343"}],"wp:attachment":[{"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/media?parent=340"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/categories?post=340"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zdebla.me\/index.php\/wp-json\/wp\/v2\/tags?post=340"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}