<?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: Odhiambo</title>
    <description>The latest articles on Forem by Odhiambo (@urbanomonte).</description>
    <link>https://forem.com/urbanomonte</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%2F3817131%2Fd40ace92-2379-459b-a632-de25c968241c.png</url>
      <title>Forem: Odhiambo</title>
      <link>https://forem.com/urbanomonte</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/urbanomonte"/>
    <language>en</language>
    <item>
      <title>A Look into SQL Query Basics</title>
      <dc:creator>Odhiambo</dc:creator>
      <pubDate>Mon, 13 Apr 2026 13:02:28 +0000</pubDate>
      <link>https://forem.com/urbanomonte/a-look-into-sql-query-basics-3ia9</link>
      <guid>https://forem.com/urbanomonte/a-look-into-sql-query-basics-3ia9</guid>
      <description>&lt;p&gt;SQL is essential for the modern data professional. It is incorporated into most tools that drive data architectures. As such, it is important to have a solid understanding of the formative fundamentals.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data definition language (DDL) VS Data Manipulation Language (DML)
&lt;/h2&gt;

&lt;p&gt;SQL queries have commands and underlying syntax which can be grouped into several categories. Two of these are data definition language and data manipulation language.&lt;/p&gt;

&lt;p&gt;Data definition language is used to modify the structure of the objects that hold data. They consist of commands such as &lt;em&gt;CREATE&lt;/em&gt;, &lt;em&gt;ALTER&lt;/em&gt;, &lt;em&gt;DROP&lt;/em&gt; among others.&lt;/p&gt;

&lt;p&gt;Data manipulation language commands are used to change the actual data. These include commands such as &lt;em&gt;INSERT&lt;/em&gt;, &lt;em&gt;UPDATE&lt;/em&gt; or even &lt;em&gt;DELETE&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Other categories include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Data query language: used to retrieve data eg. &lt;em&gt;SELECT&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Data control language: manage access and permissions to data eg. &lt;em&gt;GRANT&lt;/em&gt;, &lt;em&gt;REVOKE&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let us look at brief commands examples that form the foundational structure of SQL. As convention, SQL specific commands are written in uppercase while user defined instructions are written in lowercase. SQL queries should always end with a &lt;em&gt;semicolon (;)&lt;/em&gt;.&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="c1"&gt;-- 1. creating the schema&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;SCHEMA&lt;/span&gt; &lt;span class="n"&gt;school_schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a schema called school. Think of schema as the &lt;em&gt;folder&lt;/em&gt; that will contain all related work in one place. In the case of SQL, these include &lt;em&gt;tables&lt;/em&gt;, &lt;em&gt;views&lt;/em&gt;, &lt;em&gt;indexes&lt;/em&gt; etc. The '--' are comments which are not executed as part of the SQL command.&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="c1"&gt;--setting the search path for the session&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;search_path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;school_schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is used in &lt;em&gt;Postgresql&lt;/em&gt; to instruct that all the commands we will run should be executed in the schema given.&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="c1"&gt;--creating a students table&lt;/span&gt;
&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="n"&gt;student_id&lt;/span&gt; &lt;span class="nb"&gt;INT&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;first_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;50&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;last_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;50&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;gender&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;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;date_of_birth&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="k"&gt;class&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;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;city&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;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;--Add a phone number column&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt;
&lt;span class="n"&gt;phone_number&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;20&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Renaming a column&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="c1"&gt;--Rename credits column&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;subjects&lt;/span&gt;
&lt;span class="k"&gt;RENAME&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;credits&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;credit_hours&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deleting a column&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="c1"&gt;--Remove phone number column&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;
&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;COLUMN&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inserting data into a table&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;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;students&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;'Amina'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Wanjiku'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'f'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'2008-03-12'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Form 3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Nairobi'&lt;/span&gt;&lt;span class="p"&gt;),&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;'Brian'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Ochieng'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'m'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'2007-07-25'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Form 4'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Mombasa'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Updating a column in a record&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;UPDATE&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Nairobi'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;student_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;RETURNING&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;returning*&lt;/em&gt; keyword shows us the result of our query after we execute it. IF we don't explicitly give the &lt;em&gt;WHERE&lt;/em&gt; clause, all the records will have their &lt;em&gt;city&lt;/em&gt; column updated to &lt;em&gt;Nairobi&lt;/em&gt;. The &lt;em&gt;WHERE&lt;/em&gt; clause acts as a guardrail to prevent this.&lt;/p&gt;

&lt;p&gt;Deleting a record&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="c1"&gt;--Delete student with id 2&lt;/span&gt;
&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;student_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;RETURNING&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Intermediate commands
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;--students neither in form 3 nor form 2&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;CONCAT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_name&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="n"&gt;last_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;student&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;student&lt;/span&gt;
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'form 3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s1"&gt;'Form 2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsw2gzbtgzlaoosdfuvy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbsw2gzbtgzlaoosdfuvy.png" alt="sql not in" width="343" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Case statement to check condition first before assigning a value&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="c1"&gt;--students classification as 'Senior' or 'Junior'&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="k"&gt;CASE&lt;/span&gt;
    &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Form 3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Form 4'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="s1"&gt;'Senior'&lt;/span&gt;
    &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="s1"&gt;'Junior'&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;student_level&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;students&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1nu9qcqp2cy2w8b9uim.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj1nu9qcqp2cy2w8b9uim.png" alt="Case in sql" width="595" height="320"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A Comprehensive Guide to Publishing Power Bi Reports</title>
      <dc:creator>Odhiambo</dc:creator>
      <pubDate>Mon, 13 Apr 2026 07:02:03 +0000</pubDate>
      <link>https://forem.com/urbanomonte/a-comprehensive-guide-to-publishing-power-bi-reports-4o0k</link>
      <guid>https://forem.com/urbanomonte/a-comprehensive-guide-to-publishing-power-bi-reports-4o0k</guid>
      <description>&lt;p&gt;Once you have selected your data source in a new session on Power Bi desktop application, load data into power query to transform it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5jf0h24j5mz7ezl3275.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl5jf0h24j5mz7ezl3275.png" alt="Getting data" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In case of a mutli-sheet workbook in Excel, select sheet(s) you intend to work with. They will eventually be made into tables in Power Bi. Then click on &lt;em&gt;transform data&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faejerm7519zjb2s4u3dq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faejerm7519zjb2s4u3dq.png" alt="Transformdata" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ensure to check for inconsistent data from column filters. Standardize any inconsistent data as well as blanks and pseudo-blanks. Using the column filter we are able to see categories for each column at a glance. This would help identify blanks, inconsistencies and missing values.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cjujcw8zwgrj4fel1ju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8cjujcw8zwgrj4fel1ju.png" alt="Column filter" width="800" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;em&gt;close and apply&lt;/em&gt; to load data into Power Bi.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvyzcvnli5pmgpxoicaxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvyzcvnli5pmgpxoicaxk.png" alt="Loading to Power Bi" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the sheet from data pane and right click to rename it into something meaningful. Remember to save progress in location of our choice to avoid data loss.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87ezad6smn00g0899mbr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F87ezad6smn00g0899mbr.png" alt="Rename sheet" width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Total sales from all products.
&lt;/h2&gt;

&lt;p&gt;Since we already have sales for each individual product, we simply use SUM function to get the total for the &lt;em&gt;SalesAmount&lt;/em&gt; column. Click on &lt;em&gt;New Measure&lt;/em&gt;, give it a descriptive name and enter the function:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xy0onx8wbp4syzidwe4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xy0onx8wbp4syzidwe4.png" alt="Total sales" width="800" height="288"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Profit Margin
&lt;/h2&gt;

&lt;p&gt;Profit margin is calculated by &lt;em&gt;profit/SalesAmount * 100&lt;/em&gt;. Since we already have the total value for sales amount calculated above, we will use &lt;em&gt;SUMX&lt;/em&gt; to calculate the profit. Our new expression will be as shown:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqr3hvsyevh7ag8dspuj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqr3hvsyevh7ag8dspuj.png" alt="SumX" width="800" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;SUMX&lt;/em&gt; above encloses the profit for each row. It calculates profit for each row and also a sum at the end. For each row, this value is used to calculate the profit margin.&lt;/p&gt;

&lt;p&gt;This will allow us to filter by &lt;em&gt;country&lt;/em&gt;, &lt;em&gt;product&lt;/em&gt; in the &lt;em&gt;report view&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv158x35oietvxwnhat4x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv158x35oietvxwnhat4x.png" alt="Filter" width="800" height="393"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Change currency to USD
&lt;/h2&gt;

&lt;p&gt;Currency is changed to USD from CAD for all columns that have currency using the formula below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shipping cost to USD
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkgqmmm112vfw0xcgu14l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkgqmmm112vfw0xcgu14l.png" alt="Shipping" width="800" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Sales Amount to USD
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06pe31xg447c5ri5lxii.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F06pe31xg447c5ri5lxii.png" alt="Sales" width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Profit to USD
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpbmtu7m37zhvoopttbu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpbmtu7m37zhvoopttbu.png" alt="Profit" width="800" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Missing or incorrect values
&lt;/h2&gt;

&lt;p&gt;Missing data values can be standardized as pseudo blanks for text columns or to be null for numbers.&lt;/p&gt;

&lt;p&gt;In addressing missing numeric values, median is the best option as it accounts for skewed data. Mode is recommended for text, categorical or nominal categorical data. Mean is advised for data with normal distributed data.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Model data
&lt;/h2&gt;

&lt;p&gt;Modelling our data involves creating dimensions tables and a fact table. Click on &lt;em&gt;Transform data&lt;/em&gt; in Power Bi to open Power Query. Duplicate the existing table to the number of total tables (&lt;em&gt;dimension tables and fact tables&lt;/em&gt;) needed.&lt;/p&gt;

&lt;p&gt;Except for the fact table, columns not needed in each dimension table are deleted. Columns in the &lt;em&gt;fact table&lt;/em&gt; are kept as is to use in the subsequent steps of creating unique identifiers for all &lt;em&gt;dimension tables&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Click on &lt;em&gt;Close &amp;amp; Apply&lt;/em&gt; to effect the changes and return to Power Bi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip&lt;/strong&gt;: Always keep a copy of the original table/data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Date Table
&lt;/h3&gt;

&lt;p&gt;To create a date table, click on the &lt;em&gt;New Table&lt;/em&gt; command in Power Bi.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2a2wu13hc72w9qlfb0k9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2a2wu13hc72w9qlfb0k9.png" alt="Date" width="510" height="437"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the formula below to create the table:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xavtkda8d2whuontva7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xavtkda8d2whuontva7.png" alt="Creating date table" width="800" height="442"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;CALENDARAUTO()&lt;/em&gt; generate a new date column based on all the dates in our data. To limit the use of possible unnecessary date columns that might exist in our data, eg. &lt;em&gt;Date of Birth&lt;/em&gt;, we create new variables and determine the range our date should fall in. In this example, the &lt;em&gt;MinDate&lt;/em&gt; looks for the earliest date an order was placed and the &lt;em&gt;MaxDate&lt;/em&gt; returns the most recent date for delivery.&lt;/p&gt;

&lt;p&gt;The filter is then used to give &lt;em&gt;CALENDARAUTO()&lt;/em&gt; the date range to filter from based on these two values.&lt;/p&gt;

&lt;p&gt;The other Date-related columns are derived from the date column returned by &lt;em&gt;CALENDARAUTO()&lt;/em&gt; function.&lt;/p&gt;

&lt;p&gt;Here is a view of our tables after the steps.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0h7u5do2etdvcxja6fi6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0h7u5do2etdvcxja6fi6.png" alt="Tables" width="570" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating unique identifiers
&lt;/h3&gt;

&lt;p&gt;All our dimension tables will need unique identifiers to be linked to the fact table.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create Unique ID in the dimension table
&lt;/h4&gt;

&lt;p&gt;Click &lt;em&gt;CustomerEmail&lt;/em&gt; from the customers table and select &lt;em&gt;Remove Duplicates&lt;/em&gt; from the drop down.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwi44jl4pxzyc73jkiclr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwi44jl4pxzyc73jkiclr.png" alt="Remove duplicates" width="800" height="345"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unique email identifiers remain.&lt;/p&gt;

&lt;p&gt;From the &lt;em&gt;Add Column&lt;/em&gt; tab, click on &lt;em&gt;Index Column&lt;/em&gt; and the initiator of choice, in this case, &lt;em&gt;Custom&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxm0u108j1qk3g8hbd9w6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxm0u108j1qk3g8hbd9w6.png" alt="Custom" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Define the desired index format and increment and click &lt;em&gt;OK&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1qgq2zbifs0uf2iceh8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1qgq2zbifs0uf2iceh8.png" alt="Index" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I rename the column to &lt;em&gt;CustomerID&lt;/em&gt;, this is what we will use to join it in the &lt;em&gt;fact table&lt;/em&gt;. I also change the type to text. This just as a personal preference for columns that eventually may include a lot of records.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5usev9vsalz6ey0u19o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd5usev9vsalz6ey0u19o.png" alt="New column" width="402" height="195"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;NOTE: REPEAT THIS PROCESS FOR THE OTHER DIMENSION TABLES&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Merge the Fields from the tables
&lt;/h4&gt;

&lt;p&gt;Still in the Power Query editor, click on the &lt;em&gt;fact table&lt;/em&gt; and select &lt;em&gt;Merge Queries&lt;/em&gt; from the ribbon.&lt;/p&gt;

&lt;p&gt;Select &lt;em&gt;Left Outer Join&lt;/em&gt; with the &lt;em&gt;fact table&lt;/em&gt; as the first table. You see from the image below we get all records matching. Click ok.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz74gle1z5uxn24lmxle1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz74gle1z5uxn24lmxle1.png" alt="Merge queries" width="800" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the expand tables icon.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzb5wbpiz0kkj87svnhfw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzb5wbpiz0kkj87svnhfw.png" alt="Expand table" width="395" height="174"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deselect all column names except the &lt;em&gt;CustomerID&lt;/em&gt;. Our new fact table will have this column included.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fez7lcqt0vjs9rn6lfs8m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fez7lcqt0vjs9rn6lfs8m.png" alt="New id column" width="800" height="553"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;em&gt;CustomerID&lt;/em&gt; is now included in the &lt;em&gt;fact table&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzv6tnufohklywk3w706f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzv6tnufohklywk3w706f.png" alt="New table" width="800" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Repeat for the other dimension tables.&lt;/p&gt;

&lt;p&gt;The Relationship and view should be as shown&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3d3rrqyiasjbpqlumrj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3d3rrqyiasjbpqlumrj.png" alt="Relationship" width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Report and Dashboard
&lt;/h2&gt;

&lt;p&gt;Go to the report view and select visualization build from the side panel as needed. Add your key overview metrics from the different values. This will from the dashboard as shown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuga0kbbc92dnhspzyphs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuga0kbbc92dnhspzyphs.png" alt="Report" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save your work and click on publish. Log in to a Power Bi account from the Power Bi Service online and select the option to create a workspace.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8vmg22rsiyndaclp0ohm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8vmg22rsiyndaclp0ohm.png" alt="Workspace" width="614" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Give the workspace a name. Log in to the Power Bi account from your desktop application and click on publish. Choose the same workspace created earlier to publish the report to. You have now published your report.&lt;/p&gt;

&lt;p&gt;Create a new page on the Power Bi desktop application and give it a relevant name for specific metrics to be shown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fao7i4egzxxh9ccw8agka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fao7i4egzxxh9ccw8agka.png" alt="Report app" width="635" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will form the individual reports of your work.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncf0z7ue3yv5hxv1fxlx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncf0z7ue3yv5hxv1fxlx.png" alt="Naming reports" width="792" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The published work should reflect on the online Power Bi service.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felx5tsnahfkqlbqnnyjy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felx5tsnahfkqlbqnnyjy.png" alt="Work online" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Embedding
&lt;/h3&gt;

&lt;p&gt;To embed the report in another online document such as a webpage, click on  &lt;em&gt;File&lt;/em&gt; then select the &lt;em&gt;Embed report&lt;/em&gt; then &lt;em&gt;Website or portal&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2lbzwbhjy0b9hwvmazkx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2lbzwbhjy0b9hwvmazkx.png" alt="Embed" width="800" height="479"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the resulting iFrame for embedding inside a html document.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuu3in26sqhpfvt54w0o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvuu3in26sqhpfvt54w0o.png" alt="Iframe" width="800" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95lu95ej1vnuuc0ui5ki.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95lu95ej1vnuuc0ui5ki.png" alt="Embed iframe" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your Power Bi Report page will appear on the html document.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwhagiztrzd0770nxrmz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdwhagiztrzd0770nxrmz.png" alt="Live document" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>beginners</category>
      <category>microsoft</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Understanding Data Modeling in Power BI: Joins, Relationships, and Schemas Explained</title>
      <dc:creator>Odhiambo</dc:creator>
      <pubDate>Mon, 30 Mar 2026 16:37:52 +0000</pubDate>
      <link>https://forem.com/urbanomonte/understanding-data-modeling-in-power-bi-joins-relationships-and-schemas-explained-4hni</link>
      <guid>https://forem.com/urbanomonte/understanding-data-modeling-in-power-bi-joins-relationships-and-schemas-explained-4hni</guid>
      <description>&lt;p&gt;Many times while working with relational data, there is need to get context information from different data tables. Understanding how to perform modelling when working with such situations is essential. Let us look at some data modelling concepts when working with Power Bi.&lt;/p&gt;

&lt;h3&gt;
  
  
  Joins
&lt;/h3&gt;

&lt;p&gt;In Power Bi, joins are called &lt;em&gt;Merge queries&lt;/em&gt;. This is when two tables are joined together depending on matching values from columns. At least one column in the two tables must have matching values eg. an &lt;em&gt;id&lt;/em&gt; appearing both in &lt;em&gt;users table&lt;/em&gt; and a similar matching &lt;em&gt;id&lt;/em&gt; value appearing in &lt;em&gt;subscriptions table&lt;/em&gt;. The names of the two columns do not need to be same, but the underlying values must match.&lt;/p&gt;

&lt;p&gt;In most cases, this involves a &lt;em&gt;primary key&lt;/em&gt; from one table and a &lt;em&gt;foreign key&lt;/em&gt; in the other table. To perform joins in Power Bi, we select &lt;em&gt;Merge queries&lt;/em&gt; command from the home tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwmu2ta66gbx8vn8jnsx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwmu2ta66gbx8vn8jnsx.png" alt="Merge queries command" width="800" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;

&lt;p&gt;Several types of joins are available in Power Bi:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;inner join:&lt;/strong&gt; returns only matching rows from both the left and right tables&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyx18egk2a562qnpzsi1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxyx18egk2a562qnpzsi1.png" alt="inner join" width="463" height="305"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;left outer join:&lt;/strong&gt; returns all the rows from left table but only the rows from the right table that have a match&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93scdb8sy3oeecxm2jl8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F93scdb8sy3oeecxm2jl8.png" alt="left outer join" width="464" height="379"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;right outer join:&lt;/strong&gt; returns all the rows from right table but only the rows from the left table that have a match&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7w4cq7bh76g7vc61cgl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr7w4cq7bh76g7vc61cgl.png" alt="right outer join" width="464" height="305"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;full outer join:&lt;/strong&gt; returns all the rows from both the left and right tables&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxr421h3qy7knfuio91wl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxr421h3qy7knfuio91wl.png" alt="full outer join" width="464" height="404"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;left anti join:&lt;/strong&gt; returns only records from left table that do not have matching rows in the right table&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpr0ut74p3zlwe7q1isq2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpr0ut74p3zlwe7q1isq2.png" alt="left anti join" width="464" height="356"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;right anti join:&lt;/strong&gt; returns only records from right table that do not have matching rows in the left table&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fad3g95nul0dkslbnlt94.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fad3g95nul0dkslbnlt94.png" alt="right anti join" width="463" height="305"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;fuzzy merge:&lt;/strong&gt; this is only supported over text columns. It aims to provide a more standardadized way of representing text data in a columns eg. where distinct names are misspelled eg Vollvo instead of Volvo. It it preceded by another join type, typically, left outer join. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgqn6f623twbfu496dbq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgqn6f623twbfu496dbq.png" alt="fuzzy match" width="522" height="575"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  Sample goal of fuzzy join from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;cross join:&lt;/strong&gt; results in a Cartesian-like result from the two tables&lt;br&gt;
you first select a table of interest then click on &lt;em&gt;custom column&lt;/em&gt; command from the &lt;em&gt;Add column&lt;/em&gt; tab on the ribbon.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2pcp6vqztyx7q5dp0rwm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2pcp6vqztyx7q5dp0rwm.png" alt="custom cross join" width="728" height="511"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Enter any name for the new custom column in the dialogue window that appears. In the &lt;em&gt;Custom column formula*&lt;/em&gt; enter the name of the other table or query. Here it is called &lt;em&gt;Colors&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fexlqv18l0qsap20ja3df.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fexlqv18l0qsap20ja3df.png" alt="custom column" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Select &lt;em&gt;ok&lt;/em&gt; and also &lt;em&gt;expand the new column&lt;/em&gt; and click &lt;em&gt;ok&lt;/em&gt; again to view final result.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4igw88383ff8h1qdf0ca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4igw88383ff8h1qdf0ca.png" alt="cross join" width="372" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Image from &lt;em&gt;learn.microsoft.com&lt;/em&gt;
&lt;/h6&gt;

&lt;h3&gt;
  
  
  Relationships
&lt;/h3&gt;

&lt;p&gt;There are 4 main types of relationships called &lt;strong&gt;&lt;em&gt;cardinality&lt;/em&gt;&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;1. Many to one(*:1):&lt;/em&gt; It is the default. A column can have many instances of a value and only have one instance of the same value in the other table, known as a lookup table.&lt;br&gt;
&lt;em&gt;2. One to one(1:1):&lt;/em&gt; A columns can have only one instance of a value and also only one instance of the value in the other table.&lt;br&gt;
&lt;em&gt;3. One to many(1:*):&lt;/em&gt; A columns has only one instance of a value but can have many instances in the other table&lt;br&gt;
&lt;em&gt;4. Many to many(&lt;em&gt;:&lt;/em&gt;):&lt;/em&gt; There are no unique constraints on values in the tables.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Active relationships&lt;/strong&gt;&lt;/em&gt; in Power Bi are shown by solid continuous lines while inactive relationships are shown by dotted lines. Only one active path exists between tables and this is used to filter data for visuals.&lt;/p&gt;

&lt;h6&gt;
  
  
  Joins vs relationships
&lt;/h6&gt;

&lt;p&gt;From the foregoing, we can see that joins physically merge tables while relationships only show linkages between tables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schemas
&lt;/h3&gt;

&lt;p&gt;In Power Bi, schemas describe how your data is organized and structured. A well designed data model improves the performance of your queries as well as usability of in DAX.&lt;/p&gt;

&lt;p&gt;A few concepts are worth noting when dealing with schemas in Power Bi:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Dimension tables&lt;/em&gt;: These tables describe the things being modeled such as products or places.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Fact tables&lt;/em&gt;: They store observations or events and contain dimension key columns.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  1. Star schema
&lt;/h4&gt;

&lt;p&gt;Tables are classified either as dimension of fact tables.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faguln2i0kxr63u5bfjay.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faguln2i0kxr63u5bfjay.png" alt="star schema" width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  star schema from &lt;em&gt;radacad.com&lt;/em&gt;
&lt;/h6&gt;

&lt;p&gt;&lt;em&gt;Normalizing tables&lt;/em&gt; in star schema involves storing data in fact tables by avoiding repetition.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Snowflake
&lt;/h4&gt;

&lt;p&gt;It is some sort of a normalized version of star schema. Dimension tables are broken down further into sub-dimensions and end up forming branch-like structure.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05jo3ylvygunqs5sdbv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05jo3ylvygunqs5sdbv0.png" alt="snowflake schema" width="562" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Image from &lt;em&gt;mmsqltips.com&lt;/em&gt;
&lt;/h6&gt;

&lt;h4&gt;
  
  
  3. Flat Table (DLAT)
&lt;/h4&gt;

&lt;p&gt;Data is entered and consolidated into one single table. The table is usually very wide and has no relationship with other tables.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffcduo5f1lxwxa8zu91ns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffcduo5f1lxwxa8zu91ns.png" alt="flat table" width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;
  
  
  Image by &lt;em&gt;Firat&lt;/em&gt; on &lt;em&gt;medium.com&lt;/em&gt;
&lt;/h6&gt;

&lt;p&gt;It is called DLAT(denormalized large aggregation table)&lt;/p&gt;

&lt;h3&gt;
  
  
  Role playing dimensions
&lt;/h3&gt;

&lt;p&gt;These occur when a single dimension table can be used to filter a fact table. A fact table of sales, for instance, can be filtered based on the dates, such as &lt;em&gt;order_date&lt;/em&gt;, &lt;em&gt;shipping_date&lt;/em&gt; to show these specific analysis for dates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common modelling issues in Power Bi
&lt;/h3&gt;

&lt;p&gt;Some common issues you might run into when working with Power Bi include the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Overloading the model: Trying to load everything instead of just what is needed from the slow. This might result in slow query processes. Reduce the number of columns used and remove any unnecessary field to improve the model.&lt;/li&gt;
&lt;li&gt;Overusing the calculation to create new columns instead of just creating a new measure can lead to excessive use of RAM. It is recommended to use measures for aggregation and only use calculated columns when necessary.&lt;/li&gt;
&lt;li&gt;Ignoring data types: Data should always be in the correct types to improve on the model. It is advisable to first transform the data in Power Query before loading.&lt;/li&gt;
&lt;li&gt;Misconfiguring the table relationships can lead to circular dependencies or broken relationships. Particularly, using many-to-many relationships inaccurately can lead to double counts and eventual inaccurate data.&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>microsoft</category>
      <category>datascience</category>
    </item>
    <item>
      <title>How Linux is Used in Real-World Data Engineering (For Beginners)</title>
      <dc:creator>Odhiambo</dc:creator>
      <pubDate>Fri, 27 Mar 2026 10:15:59 +0000</pubDate>
      <link>https://forem.com/urbanomonte/how-linux-is-used-in-real-world-data-engineering-for-beginners-3i9</link>
      <guid>https://forem.com/urbanomonte/how-linux-is-used-in-real-world-data-engineering-for-beginners-3i9</guid>
      <description>&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;1. A working public IP address to an Ubuntu server on the cloud&lt;/em&gt;&lt;br&gt;
&lt;em&gt;2. Access to admin user credentials (password or private key for key-based authentication)&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Linux For The Cloud
&lt;/h4&gt;

&lt;p&gt;Data engineering is increasingly seeing the uptake of cloud infrastructure as essential in how firms manage their data. From storage, automation, and analysis, many tools and resources are now deployed in the cloud.&lt;/p&gt;

&lt;p&gt;Working on Linux environments is an unspoken necessary skill for data engineers. There are tools and processes you will come across in the data engineering lifecycle for which you need to have skills on Linux. Linux servers are almost an intrinsic choice for cloud servers. Their ubiquity on the cloud is because they are lightweight and highly optimized for the cloud.&lt;/p&gt;

&lt;p&gt;As such, navigating and running commands from the Linux terminal is the focus of this article. It gives you a beginner friendly feel to working from the terminal interface.&lt;/p&gt;
&lt;h4&gt;
  
  
  Accessing the server
&lt;/h4&gt;

&lt;p&gt;You need to be able to access the server remotely to do routine management and maintenance tasks. Open a terminal and type the following command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;replace the IP address after the &lt;strong&gt;@&lt;/strong&gt; sign with the actual server public IP address. The first time you log in to the server, your computer will prompt you to add the host to your local machine addresses of known hosts. Click &lt;code&gt;yes&lt;/code&gt; to accept this step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root@143.110.225.134&lt;span class="s1"&gt;'s password: 
Welcome to Ubuntu 24.04.4 LTS (GNU/Linux 6.8.0-71-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/pro

 System information as of Wed Mar 25 14:54:56 UTC 2026

  System load:  0.0               Processes:             137
  Usage of /:   4.8% of 47.39GB   Users logged in:       4
  Memory usage: 20%               IPv4 address for eth0:143.110.225.134
  Swap usage:   0%                IPv4 address for eth0: 10.48.0.5

Expanded Security Maintenance for Applications is not enabled.

0 updates can be applied immediately.

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


*** System restart required ***
Last login: Wed Mar 25 14:35:08 2026 from 41.99.105.22
root@ubuntu:~#
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;_NOTE:&lt;/code&gt; The numbers are fictional for demo only.&lt;br&gt;
The line &lt;code&gt;root@ubuntu&lt;/code&gt; indicates that we are logged in as user root and the name of the host/server machine is ubuntu. If you run the &lt;code&gt;pwd&lt;/code&gt; command, you should see that you are inside the root folder as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root@ubuntu:~# &lt;span class="nb"&gt;pwd&lt;/span&gt;
/root
root@ubuntu:~# 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Creating a user
&lt;/h4&gt;

&lt;p&gt;Now let us create a user called &lt;em&gt;odhiambo&lt;/em&gt; on this system. We use the &lt;code&gt;_adduser_&lt;/code&gt; command as shown below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root@ubuntu:~# &lt;span class="nb"&gt;sudo &lt;/span&gt;adduser odhiambo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will get a prompt to set and confirm the password of the user. You will also get several optional prompts including to enter the full name and phone details. We skip these optional steps by just pressing &lt;em&gt;Enter&lt;/em&gt; at each prompt.&lt;/p&gt;

&lt;h4&gt;
  
  
  Giving the user administrative privileges
&lt;/h4&gt;

&lt;p&gt;The user &lt;em&gt;odhiambo&lt;/em&gt; does not have permission to run administrative tasks on the system. We then grant these privileges by adding the user &lt;em&gt;odhiambo&lt;/em&gt; to the &lt;code&gt;sudo&lt;/code&gt; group with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;root@ubuntu:~# &lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;odhiambo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first &lt;code&gt;sudo&lt;/code&gt; is to allow us to run the command without running into permission denied issues&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;usermod&lt;/code&gt; command is for modifying system user settings&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;-a&lt;/code&gt; instructs the system to &lt;em&gt;append&lt;/em&gt; the user with the &lt;code&gt;G&lt;/code&gt; specifying the append is to a &lt;code&gt;group&lt;/code&gt;. So the command is &lt;em&gt;appending to a group&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The group the user is being appended to is called &lt;em&gt;sudo&lt;/em&gt;, which is the superuser group. This will give the user full access to all the privileges. However, they should invoke the &lt;code&gt;_sudo_&lt;/code&gt; keyword before running these commands&lt;/p&gt;

&lt;p&gt;The username being modified is &lt;em&gt;odhiambo&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Logging in with our user account
&lt;/h4&gt;

&lt;p&gt;We are now able to log on to the server using our user.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;We should see that the terminal should now indicate that we are logged in as &lt;em&gt;odhiambo&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;odhiambo@ubuntu:~&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  A glimpse into the Linux file structure
&lt;/h4&gt;

&lt;p&gt;For new Linux users, one of the most important things to have a fundamental understanding on  is the Linux file structure. The top-most level folder structure typically looks as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;odhiambo@ubuntu:~&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /
bin                home               mnt   sbin.usr-is-merged  usr
bin.usr-is-merged  lib                opt   snap                var
boot               lib64              proc  srv
cdrom              lib.usr-is-merged  root  swap.img
dev                lost+found         run   sys
etc                media              sbin  tmp
odhiambo@ubuntu:~&lt;span class="nv"&gt;$ &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we have used the &lt;code&gt;ls&lt;/code&gt; command that lists all the files in a folder. The &lt;code&gt;/&lt;/code&gt; sign indicates that we want to view the files in the&lt;code&gt;root&lt;/code&gt; ie _top most level_folder.While this file structure is not the focus of this article, I want to talk about the &lt;code&gt;home folder&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Notice that our path on the terminal when we logged in as &lt;em&gt;odhiambo&lt;/em&gt; included a tilde &lt;code&gt;~&lt;/code&gt; ie &lt;code&gt;odhiambo@ubuntu:~$&lt;/code&gt;. This is a shorthand to show that we are in our user's home folder, in this case, &lt;em&gt;odhiambo&lt;/em&gt;'s home folder.&lt;/p&gt;

&lt;p&gt;User's &lt;em&gt;home&lt;/em&gt; folder is different from the &lt;em&gt;home&lt;/em&gt; folder at the root level. All user accounts created on the system will have a folder with their name inside the root level home folder eg. &lt;em&gt;/home/odhiambo&lt;/em&gt;. So in actuality, the path &lt;code&gt;odhiambo@ubuntu:~$&lt;/code&gt; corresponds to &lt;code&gt;odhiambo@ubuntu:~$/home/odhiambo&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Handling files
&lt;/h4&gt;

&lt;p&gt;A data engineer works a lot with files on the terminal. This includes making edits to configuration files, or making creating script from the terminal. Knowing the basics of file handling in data engineering in Linux server environment is important.&lt;/p&gt;

&lt;h6&gt;
  
  
  1. Creating files
&lt;/h6&gt;

&lt;p&gt;The most basic way to create a file is using the &lt;code&gt;touch&lt;/code&gt; command with the file name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;orders.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a file called &lt;em&gt;orders.txt&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;orders.txt Manual.md suppliers.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create multiple files&lt;/p&gt;

&lt;h6&gt;
  
  
  2. Deleting files
&lt;/h6&gt;

&lt;p&gt;use &lt;code&gt;rm&lt;/code&gt; to remove a file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm &lt;/span&gt;orders.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h6&gt;
  
  
  3. Listing files
&lt;/h6&gt;

&lt;p&gt;We have already hinted at this before. The &lt;code&gt;ls&lt;/code&gt; command lists files and folders&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will list all files and folders on a path. File and folders are distinguished based on the colors. Files also may have an extension.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lists all files and folders, including hidden files and folders.&lt;/p&gt;

&lt;h6&gt;
  
  
  4. Moving files
&lt;/h6&gt;

&lt;p&gt;Moving a file does not leave a copy behind. We use the &lt;code&gt;mv&lt;/code&gt; command followed with the &lt;em&gt;source file&lt;/em&gt; followed by the &lt;em&gt;destination path&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mv &lt;/span&gt;orders.txt completed/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This moves the orders.txt to a folder called completed inside the current path. If the folder does not exist, the command will fail.&lt;/p&gt;

&lt;h6&gt;
  
  
  5. Copying files
&lt;/h6&gt;

&lt;p&gt;The &lt;code&gt;cp&lt;/code&gt; command is used to copy files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp &lt;/span&gt;orders.txt completed/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will copy the &lt;em&gt;orders.txt&lt;/em&gt; file into a folder called &lt;em&gt;completed&lt;/em&gt; in the current path. If the folder does not exist, the command fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scp orders.txt odhiambo@143.110.225.134:/home/odhiambo/orders/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will copy the &lt;em&gt;orders.txt&lt;/em&gt; file from our &lt;em&gt;local machine&lt;/em&gt; to the server inside the &lt;em&gt;orders folder&lt;/em&gt; on the path shown. &lt;em&gt;Note:&lt;/em&gt; You will be prompted to enter the server password. The &lt;code&gt;scp&lt;/code&gt; allows to securely copy files over the internet.&lt;/p&gt;

&lt;h4&gt;
  
  
  File permissions
&lt;/h4&gt;

&lt;p&gt;The last thing we will look at is a brief overview of file permissions in Linux. Use the &lt;code&gt;ls -l&lt;/code&gt; command to view file permissions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;odhiambo@ubuntu:~/&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
total 0
&lt;span class="nt"&gt;-rw-rw-r--&lt;/span&gt; 1 odhiambo odhiambo 0 Mar 27 13:04 orders.txt
odhiambo@ubuntu:~/&lt;span class="nv"&gt;$ &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Permissions in Linux are &lt;em&gt;&lt;em&gt;read&lt;/em&gt;&lt;/em&gt;, &lt;em&gt;&lt;em&gt;write&lt;/em&gt;&lt;/em&gt; and &lt;em&gt;&lt;em&gt;execute&lt;/em&gt;&lt;/em&gt; with their corresponding values as &lt;em&gt;4&lt;/em&gt;, &lt;em&gt;2&lt;/em&gt; and &lt;em&gt;1&lt;/em&gt;. So a value of &lt;em&gt;&lt;em&gt;7&lt;/em&gt;&lt;/em&gt; means a user has all the three permissions (4+2+1).&lt;/p&gt;

&lt;p&gt;In addition, the &lt;code&gt;ls -l&lt;/code&gt; commands lists permissions in a 3 part string, &lt;em&gt;user&lt;/em&gt;, &lt;em&gt;group&lt;/em&gt; and &lt;em&gt;other&lt;/em&gt;. &lt;em&gt;r&lt;/em&gt;, &lt;em&gt;w&lt;/em&gt; and &lt;em&gt;x&lt;/em&gt; correspond to the &lt;em&gt;read&lt;/em&gt;, &lt;em&gt;write&lt;/em&gt; and &lt;em&gt;execute&lt;/em&gt; permissions.&lt;/p&gt;

&lt;p&gt;The image below shows a summary of this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzycaqdwoo03jhp728k9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftzycaqdwoo03jhp728k9.png" alt="Permissions in Linux" width="800" height="695"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h6&gt;photo from bytebytego.com&lt;/h6&gt;

&lt;h6&gt;
  
  
  cover photo by &lt;em&gt;pressfoto&lt;/em&gt; on &lt;em&gt;freepik&lt;/em&gt;
&lt;/h6&gt;

</description>
      <category>linux</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>How To Install Microsoft Power Bi On VirtualBox In Ubuntu</title>
      <dc:creator>Odhiambo</dc:creator>
      <pubDate>Wed, 11 Mar 2026 08:40:35 +0000</pubDate>
      <link>https://forem.com/urbanomonte/how-to-install-microsoft-power-bi-on-virtualbox-in-ubuntu-14mc</link>
      <guid>https://forem.com/urbanomonte/how-to-install-microsoft-power-bi-on-virtualbox-in-ubuntu-14mc</guid>
      <description>&lt;p&gt;Installing Microsoft Power Bi on Ubuntu is a fairly beginner-friendly process. We first start by spinning a virtual machine on our Ubuntu. VirtualBox is chosen for this case for its prominent use in the linux community.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Download Virtualbox
&lt;/h4&gt;

&lt;p&gt;Go to the download page of virtualbox linux download page &lt;a href="https://www.virtualbox.org/wiki/Linux_Downloads" rel="noopener noreferrer"&gt;here&lt;/a&gt; and download the deb package for your Ubuntu distribution. To know the version of Ubuntu you are running open a terminal and type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lsb_release &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First ensure to update your package manager by typing &lt;code&gt;sudo apt update&lt;/code&gt; on your terminal.&lt;/p&gt;

&lt;p&gt;Install the .deb file you have downloaded. To do this, open the .deb download location and install it using &lt;code&gt;sudo dpkg -i your_virtualbox_download.deb&lt;/code&gt; eg&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dpkg &lt;span class="nt"&gt;-i&lt;/span&gt; virtualbox-7.2_7.2.6-172322~Ubuntu~noble_amd64.deb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Download the Windows .iso image
&lt;/h4&gt;

&lt;p&gt;Next, we need to download an iso image which we will use to run the windows environment on Virtualbox. Go to &lt;a href="https://www.microsoft.com/en-ca/software-download/windows10iso" rel="noopener noreferrer"&gt;this link&lt;/a&gt; and download an iso image for Windows.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Create a virtual machine
&lt;/h4&gt;

&lt;p&gt;With the Windows .iso image downloaded, launch the Virtualbox app from the app launcher. Click on &lt;strong&gt;New&lt;/strong&gt; from the home dashbord.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fooe6lrs8vxzc7yh4ml6h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fooe6lrs8vxzc7yh4ml6h.png" alt="virtual box home dashboard" width="697" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow the series of prompts filling out the necessary details such as the name of the virtual machine. Select the .iso file you downloaded from the ISO Image dropdown.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxkxwh7fhgilrkddnwgp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxkxwh7fhgilrkddnwgp.png" alt="ISO Image select" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Follow the prompts and enter all the necessary details. Remember your username and password as we will need them to log in to our Windows virtual machine. Assign a minimum of 4GB Ram in the Base Memory section. 6GB Ram is assigned here.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foczjldp0moahp512rvph.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foczjldp0moahp512rvph.png" alt="Assigning RAM" width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;code&gt;Finish&lt;/code&gt; and allow it some time to install all the necessary requirements for your Windows environment.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Open the Windows Virtual Machine
&lt;/h4&gt;

&lt;p&gt;After the Windows installation, enter your username and password when prompted. You now have access to the Windows virtual machine.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s2uakud9gjpjaxxe5ck.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s2uakud9gjpjaxxe5ck.png" alt="Windows environment" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Install Power BI
&lt;/h4&gt;

&lt;p&gt;Launch the Microsoft Store, search for Power BI and proceed with guided steps on the installation.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0g4q072p86opnmkllf74.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0g4q072p86opnmkllf74.png" alt="Power Bi MS Store" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively, launch the &lt;code&gt;Edge&lt;/code&gt; browser and search for Power Bi installation.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flnh6ndkfqru9aq4cwpwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flnh6ndkfqru9aq4cwpwg.png" alt="Edge power bi" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Open the application after installation. Congratulations, you now have Power BI on your Ubuntu system.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F549p0lpqxw6n0xs9sc0c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F549p0lpqxw6n0xs9sc0c.png" alt="open powerbi" width="800" height="433"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxvc2bqipco0otdeaah7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnxvc2bqipco0otdeaah7.png" alt="Blank power bi" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Tips
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Always assign sufficient RAM to allow the resources to be well served.&lt;/li&gt;
&lt;li&gt;Remember to keep your username and password secure.&lt;/li&gt;
&lt;li&gt;Shut down the virtual machine from the Virtualbox window after use. Click on &lt;code&gt;File&lt;/code&gt; then &lt;code&gt;Close&lt;/code&gt; and select the &lt;code&gt;Power off the machine&lt;/code&gt;
&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fezf9g0o3yqrl2ifmixi6.png" alt="Power off" width="386" height="276"&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>linux</category>
      <category>virtualmachine</category>
      <category>powerbi</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
