<?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>DEV Community: Joy Mbugua</title>
    <description>The latest articles on DEV Community by Joy Mbugua (@joy_mbugua_f9c6ecc05289ef).</description>
    <link>https://dev.to/joy_mbugua_f9c6ecc05289ef</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3952492%2F6210af66-4d77-4ce3-bdee-02ac2b218870.png</url>
      <title>DEV Community: Joy Mbugua</title>
      <link>https://dev.to/joy_mbugua_f9c6ecc05289ef</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/joy_mbugua_f9c6ecc05289ef"/>
    <language>en</language>
    <item>
      <title>Building My First Real Database: What a Weekend SQL Assignment Taught Me About Postgres (and Git)</title>
      <dc:creator>Joy Mbugua</dc:creator>
      <pubDate>Sat, 18 Jul 2026 10:21:58 +0000</pubDate>
      <link>https://dev.to/joy_mbugua_f9c6ecc05289ef/building-my-first-real-database-what-a-weekend-sql-assignment-taught-me-about-postgres-and-git-4mc8</link>
      <guid>https://dev.to/joy_mbugua_f9c6ecc05289ef/building-my-first-real-database-what-a-weekend-sql-assignment-taught-me-about-postgres-and-git-4mc8</guid>
      <description>&lt;p&gt;This weekend I got an assignment that sounded simple on paper: build a small school database for a fictional secondary school called Greenwood Academy, fill it with data, and then write a bunch of queries against it. Three tables. Thirty questions. Easy, right?&lt;/p&gt;

&lt;p&gt;It was not "&lt;strong&gt;easy&lt;/strong&gt;," but it was one of those exercises where you can actually feel yourself understanding SQL instead of just copying syntax from a tutorial. Here's what the process looked like, and a few things that tripped me up along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up the database
&lt;/h2&gt;

&lt;p&gt;I'm using PostgreSQL hosted on Aiven, with DBeaver as my SQL client. The first step was creating a schema basically a named container to keep all of Greenwood Academy's tables separate from anything else in the database:&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;SCHEMA&lt;/span&gt; &lt;span class="n"&gt;greenwood_academy&lt;/span&gt;&lt;span class="p"&gt;;&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="k"&gt;TO&lt;/span&gt; &lt;span class="n"&gt;greenwood_academy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That second line tripped me up at first. I kept looking for a &lt;code&gt;USE&lt;/code&gt; statement like you'd see in MySQL tutorials, and PostgreSQL just doesn't have one. &lt;code&gt;SET search_path&lt;/code&gt; is the equivalent-it tells PostgreSQL, "when I say &lt;code&gt;students&lt;/code&gt;, I mean &lt;code&gt;greenwood_academy.students&lt;/code&gt;" for the rest of the session.&lt;/p&gt;

&lt;p&gt;From there I created three tables:&lt;code&gt;students&lt;/code&gt;, &lt;code&gt;subjects&lt;/code&gt;, and &lt;code&gt;exam_results&lt;/code&gt;, and then immediately had to alter them: adding a &lt;code&gt;phone_number&lt;/code&gt; column to &lt;code&gt;students&lt;/code&gt;, renaming &lt;code&gt;credits&lt;/code&gt; to &lt;code&gt;credit_hours&lt;/code&gt; in &lt;code&gt;subjects&lt;/code&gt;, and then dropping that same &lt;code&gt;phone_number&lt;/code&gt; column a few questions later because the "school" changed its mind. It's a small thing, but it made &lt;code&gt;ALTER TABLE&lt;/code&gt; feel less like a random command and more like something you reach for constantly in real database work, schemas are never really "&lt;strong&gt;done&lt;/strong&gt;."&lt;/p&gt;

&lt;h2&gt;
  
  
  Filling it up and immediately breaking it
&lt;/h2&gt;

&lt;p&gt;Once the tables existed, I inserted 10 students, 10 subjects, and 10 exam results.Then the assignment had me simulate the kind of small corrections that happen in any real system: a student moves cities, a mark gets entered wrong and needs fixing, an exam result gets cancelled and needs deleting.&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;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;exam_results&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;59&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;result_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&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;exam_results&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;result_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing complicated, but it's a good reminder of why &lt;code&gt;WHERE&lt;/code&gt; clauses deserve respect.Forget one on an &lt;code&gt;UPDATE&lt;/code&gt; or &lt;code&gt;DELETE&lt;/code&gt; and you're not fixing one row, you're rewriting the whole table.&lt;/p&gt;

&lt;h2&gt;
  
  
  The query section is where it clicked
&lt;/h2&gt;

&lt;p&gt;Sections C through F were the actual querying practice: filtering with &lt;code&gt;WHERE&lt;/code&gt;, combining conditions with &lt;code&gt;AND&lt;/code&gt;/&lt;code&gt;OR&lt;/code&gt;, using &lt;code&gt;BETWEEN&lt;/code&gt;, &lt;code&gt;IN&lt;/code&gt;, &lt;code&gt;NOT IN&lt;/code&gt;, and &lt;code&gt;LIKE&lt;/code&gt;, running &lt;code&gt;COUNT()&lt;/code&gt;, and finally writing &lt;code&gt;CASE WHEN&lt;/code&gt; statements to turn raw numbers into labels.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;&lt;code&gt;CASE WHEN&lt;/code&gt;&lt;/strong&gt; questions were my favorite part of the whole assignment.&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;result_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;marks&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="n"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="s1"&gt;'Distinction'&lt;/span&gt;
        &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="s1"&gt;'Merit'&lt;/span&gt;
        &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;marks&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="s1"&gt;'Pass'&lt;/span&gt;
        &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="s1"&gt;'Fail'&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;performance&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;exam_results&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...felt like the first time in this assignment where SQL stopped being about storing data and started being about &lt;strong&gt;presenting&lt;/strong&gt; it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The part nobody warns you about: Git
&lt;/h2&gt;

&lt;p&gt;Writing the SQL was honestly the easy part.&lt;/p&gt;

&lt;p&gt;Pushing it to GitHub is where I actually got stuck.&lt;/p&gt;

&lt;p&gt;I created the repo on GitHub first, then initialized git locally, committed my files, and tried to push — only to get hit with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;! [rejected] main -&amp;gt; main (fetch first)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Turns out my GitHub repo wasn't actually empty — it already had its own README sitting there, and my local repo had a different one for the same file. Classic case of two histories that don't know about each other. The fix was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git pull origin main &lt;span class="nt"&gt;--allow-unrelated-histories&lt;/span&gt; &lt;span class="nt"&gt;--no-rebase&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which merged the two histories, dumped me into a merge conflict in &lt;code&gt;README.md&lt;/code&gt;, and forced me to actually open the file and decide what content to keep between the &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt; markers.Once I resolved it, added it, and committed the merge, the push finally went through clean.&lt;/p&gt;

&lt;p&gt;It wasn't a big deal in hindsight, but in the moment it was the most stressful five minutes of the whole assignment — way more than any SQL query. If you're newer to git, that's a totally normal thing to run into the first time you create a repo with a README both on GitHub and locally. Now I know: pick one place to create the README, not both.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd tell someone starting this assignment
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Don't skip &lt;code&gt;SET search_path&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Run your &lt;code&gt;INSERT&lt;/code&gt; statements and immediately check them with &lt;code&gt;SELECT COUNT(*)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Read every &lt;code&gt;WHERE&lt;/code&gt; clause twice before running an &lt;code&gt;UPDATE&lt;/code&gt; or &lt;code&gt;DELETE&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If your GitHub repo and your local folder both end up with a &lt;code&gt;README.md&lt;/code&gt;, expect a merge conflict.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All the SQL files are up in my repo here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/JoyM-N/sql-week2-assignment-Joy-Mbugua" rel="noopener noreferrer"&gt;sql-week2-assignment-Joy-Mbugua&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Small assignment, but a genuinely useful one, the kind where the mistakes taught me more than the parts that went smoothly.&lt;/p&gt;

</description>
      <category>sql</category>
      <category>postgres</category>
      <category>database</category>
      <category>github</category>
    </item>
    <item>
      <title>My Experience in Connecting Power BI to Local SQL and Aiven PostgreSQL(Including an SSL Certificate Fix)</title>
      <dc:creator>Joy Mbugua</dc:creator>
      <pubDate>Mon, 06 Jul 2026 19:36:02 +0000</pubDate>
      <link>https://dev.to/joy_mbugua_f9c6ecc05289ef/my-experience-in-connecting-power-bi-to-local-sql-and-aiven-postgresqlincluding-an-ssl-certificate-1cfe</link>
      <guid>https://dev.to/joy_mbugua_f9c6ecc05289ef/my-experience-in-connecting-power-bi-to-local-sql-and-aiven-postgresqlincluding-an-ssl-certificate-1cfe</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When I first started using Power BI, almost all of the datasets I worked with came from Excel files. As I continued learning more about business intelligence, I realised that most real-world applications store their data in databases instead.&lt;/p&gt;

&lt;p&gt;To understand how Power BI works with databases, I decided to try two different scenarios. First, I connected it to a database running locally on my machine. I then connected it to a cloud-hosted PostgreSQL database on Aiven to see how the process differed. While the local connection worked almost immediately, the cloud connection introduced SSL certificates, something I had never configured before.&lt;/p&gt;

&lt;p&gt;During the process I encountered a certificate trust error that initially prevented Power BI from connecting. After troubleshooting the issue and finding the solution, I thought it would be useful to document the entire process so that anyone facing the same problem can resolve it much faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting Power BI to a Local SQL Database
&lt;/h2&gt;

&lt;p&gt;If your database is running locally,for example SQL Server Express or PostgreSQL installed on your computer,the connection process is relatively straightforward. Since the database is on the same machine, there is no SSL certificate configuration required. In my case, Power BI connected successfully as soon as I entered the correct server details and authentication credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open &lt;strong&gt;Power BI Desktop&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Home - Get Data - More...&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Search for &lt;strong&gt;SQL Server&lt;/strong&gt; or &lt;strong&gt;PostgreSQL Database&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Connect&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enter the server details.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Server: localhost&lt;/li&gt;
&lt;li&gt;Database: your database name&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose your authentication method.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Connect&lt;/strong&gt; and either select &lt;strong&gt;Load&lt;/strong&gt; or &lt;strong&gt;Transform Data&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because the database was running locally, there were no certificate or encryption issues to configure. The connection worked immediately, making this the easiest part of the process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting Power BI to Aiven PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Unlike the local database, connecting to Aiven required a few additional steps. Since the database is hosted in the cloud, the connection uses a public hostname and requires SSL encryption to keep the communication secure.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7ngdmcg7f9520q4xctk5.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F7ngdmcg7f9520q4xctk5.jpeg" alt="Aiven PostgreSQL connection information including host, port and database name" width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the Connection Details
&lt;/h3&gt;

&lt;p&gt;The first thing I did was open my PostgreSQL service on Aiven and copy the connection details. These included the hostname, port number, database name, username and password. I also downloaded the CA certificate because it would later be needed for SSL.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing the Connection in DBeaver
&lt;/h3&gt;

&lt;p&gt;Before opening Power BI, I decided to test the connection in DBeaver first. I prefer using DBeaver for troubleshooting because it gives much clearer error messages whenever something isn't configured correctly.&lt;/p&gt;

&lt;p&gt;Inside the SSL settings, I imported the CA certificate downloaded from Aiven and changed the SSL mode to &lt;strong&gt;Require&lt;/strong&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqh6js1cau8wyji1pg4pz.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqh6js1cau8wyji1pg4pz.jpeg" alt="DBeaver SSL settings with the Aiven CA certificate configured" width="757" height="671"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After saving the settings, I tested the connection again and it connected successfully. This confirmed that the database itself was working correctly before moving to 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsbaat8q0mcgap8uu39sc.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsbaat8q0mcgap8uu39sc.jpeg" alt="Successful connection to the Aiven PostgreSQL database in DBeaver" width="800" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Importing Data into PostgreSQL
&lt;/h3&gt;

&lt;p&gt;Since my data was originally stored in a flat file, I used DBeaver's Import Data wizard to create a table and populate it. The wizard automatically mapped most of the columns, making the import process straightforward.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv3qcfc82689mjkcjczjh.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv3qcfc82689mjkcjczjh.jpeg" alt="DBeaver Import Data wizard mapping a CSV file to a PostgreSQL table" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After the import completed, I checked the row count to make sure every record had been transferred successfully.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F12yzaau5jl1uem09i012.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F12yzaau5jl1uem09i012.jpeg" alt="Imported data displayed in the PostgreSQL table after the transfer completed" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect Power BI to the Aiven database
&lt;/h3&gt;

&lt;p&gt;In Power BI Desktop, go to &lt;strong&gt;Get Data - PostgreSQL database&lt;/strong&gt;&lt;br&gt;
In the Server field, enter your host and port together, separated by a colon: &lt;strong&gt;your-host.aivencloud.com:16392&lt;/strong&gt;&lt;br&gt;
In Database, enter your database name (e.g. defaultdb)&lt;br&gt;
Click OK, then choose Database authentication and enter your username and password&lt;/p&gt;
&lt;h3&gt;
  
  
  The SSL Certificate Error
&lt;/h3&gt;

&lt;p&gt;This was the only part of the exercise that actually slowed me down. After entering the connection details in Power BI, I expected the connection to work because DBeaver had already connected successfully.&lt;br&gt;
Instead Power BI displayed an error to my surprise.&lt;br&gt;
At first, I assumed I had entered the wrong password or hostname. After checking everything several times, I realised those details were correct because the exact same connection was already working in DBeaver.&lt;/p&gt;

&lt;p&gt;After doing some research, I discovered that Windows simply didn't trust Aiven's certificate authority. The issue wasn't with PostgreSQL or my credentials, it was with Windows certificate validation.&lt;/p&gt;

&lt;p&gt;After importing the certificate into Windows' Trusted Root Certification Authorities store and restarting Power BI, I retried the connection. This time it connected immediately and displayed all the available tables.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxw05ioovyco3dpxwgzia.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxw05ioovyco3dpxwgzia.png" alt=" " width="758" height="737"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating Basic Measures
&lt;/h2&gt;

&lt;p&gt;Once the tables had been loaded into Power BI, I created a few simple DAX measures to confirm that everything was working correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Total Revenue =
SUM(Jcars[revenue])

Total Units Sold =
SUM(Jcars[units_sold])

Gross Profit =
[Total Revenue] -
SUMX(
    Jcars,
    Jcars[unit_cost] * Jcars[units_sold]
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The measures calculated successfully, confirming that Power BI was reading the PostgreSQL data correctly. From this point onwards, I could build visuals exactly as I would when working with any other data source.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgg9zf5267e3bc3x8shht.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgg9zf5267e3bc3x8shht.jpeg" alt="Power BI report showing DAX measures created from PostgreSQL data" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Before working on this exercise, I expected connecting Power BI to a cloud database to be much more complicated than connecting to a local database. After completing both, I realised that the overall process is almost identical. The biggest difference is that cloud databases require SSL because the connection is made over the internet.&lt;/p&gt;

&lt;p&gt;The only challenge I encountered was the certificate trust error. Once I understood that Windows simply didn't trust Aiven's certificate authority and imported the CA certificate into the Trusted Root store, the connection worked without any further issues.&lt;/p&gt;

&lt;p&gt;Besides learning how to connect Power BI to different database environments, this exercise also gave me a much better understanding of why SSL certificates are important and how cloud-hosted databases secure their connections.&lt;/p&gt;

</description>
      <category>datascience</category>
      <category>powerfuldevs</category>
      <category>sqlserver</category>
      <category>postgressql</category>
    </item>
    <item>
      <title>Connecting the Dots: Understanding Database Relationships and SQL Joins</title>
      <dc:creator>Joy Mbugua</dc:creator>
      <pubDate>Sun, 28 Jun 2026 21:16:50 +0000</pubDate>
      <link>https://dev.to/joy_mbugua_f9c6ecc05289ef/connecting-the-dots-understanding-database-relationships-and-sql-joins-24om</link>
      <guid>https://dev.to/joy_mbugua_f9c6ecc05289ef/connecting-the-dots-understanding-database-relationships-and-sql-joins-24om</guid>
      <description>&lt;p&gt;Have you ever wondered how apps like university portals know which courses a student is enrolled in, or how they pull up an instructor's full schedule in seconds?&lt;/p&gt;

&lt;p&gt;The answer lies in &lt;strong&gt;database relationships&lt;/strong&gt; - one of the most important concepts in backend development.&lt;/p&gt;

&lt;p&gt;In this article, we'll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What database relationships are and why they matter&lt;/li&gt;
&lt;li&gt;The three types of relationships: One-to-One, One-to-Many, and Many-to-Many&lt;/li&gt;
&lt;li&gt;How relationship schemas work (primary keys, foreign keys)&lt;/li&gt;
&lt;li&gt;How SQL Joins let you pull connected data from multiple tables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To keep things grounded, we'll use one running example throughout: a &lt;strong&gt;University Management System&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By the end, you won't just understand the theory, you'll see exactly how these concepts connect in a real-world scenario.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Are Database Relationships?
&lt;/h2&gt;

&lt;p&gt;A database relationship defines how data in one table connects to data in another.&lt;/p&gt;

&lt;p&gt;Instead of storing the same information repeatedly, relational databases organize data into separate tables and link them using &lt;strong&gt;keys&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think about our university system. We have a table for &lt;strong&gt;students&lt;/strong&gt; and another for &lt;strong&gt;courses&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A student can enroll in multiple courses, and each course can have many students. Rather than storing a student's full details on every course record, we store the student's info &lt;strong&gt;once&lt;/strong&gt; and create a relationship between the two tables.&lt;/p&gt;

&lt;p&gt;This keeps data clean, reduces duplication, and makes updates easy. If a student's email changes? Update it in one place - done.&lt;/p&gt;

&lt;p&gt;Here's a simple visual of what that looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+------------------+          +------------------+
| Students         |          | Courses          |
+------------------+          +------------------+
| student_id (PK)  |          | course_id (PK)   |
| name             |          | title            |
| email            |          | credits          |
+------------------+          +------------------+
          \                        /
           \                      /
            \                    /
         Enrollments (links students ↔ courses)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's look at the &lt;strong&gt;three types&lt;/strong&gt; of relationships you'll encounter.&lt;/p&gt;




&lt;h2&gt;
  
  
  Types of Database Relationships
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. One-to-One (1:1)
&lt;/h3&gt;

&lt;p&gt;Each record in Table A matches &lt;strong&gt;exactly one&lt;/strong&gt; record in Table B and vice versa.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;University example:&lt;/strong&gt; Every student has one student profile (bio, photo, address).&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 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;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;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;email&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;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Profiles 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;profiles&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;profile_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;student_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;bio&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;photo_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="k"&gt;FOREIGN&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;student_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&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="p"&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;code&gt;UNIQUE&lt;/code&gt; constraint on &lt;code&gt;student_id&lt;/code&gt; in the profiles table is what enforces the one-to-one rule; no two profiles can belong to the same student.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. One-to-Many (1:N)
&lt;/h3&gt;

&lt;p&gt;One record in Table A can relate to &lt;strong&gt;many&lt;/strong&gt; records in Table B.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;University example:&lt;/strong&gt; One department has many students. One instructor teaches many courses.&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;-- Departments 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;departments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;dept_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;dept_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;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Students table (updated)&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;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;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;email&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;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;dept_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;FOREIGN&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;dept_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;departments&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dept_id&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;p&gt;Many students share the same &lt;code&gt;dept_id&lt;/code&gt;. That's your one-to-many relationship.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Many-to-Many (M:N)
&lt;/h3&gt;

&lt;p&gt;Records in Table A can relate to &lt;strong&gt;many&lt;/strong&gt; records in Table B, and records in Table B can relate to many in Table A.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;University example:&lt;/strong&gt; Students enroll in many courses. Each course has many students enrolled.&lt;/p&gt;

&lt;p&gt;You can't link these directly but instead you need a &lt;strong&gt;junction table&lt;/strong&gt; (also called a bridge or pivot 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="c1"&gt;-- Enrollments (junction 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;enrollments&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;enrollment_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;student_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;course_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;enrolled_date&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;FOREIGN&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;student_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&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="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;FOREIGN&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;course_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;course_id&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;h2&gt;
  
  
  Understanding Relationship Schemas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Primary Keys
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Primary Key (PK)&lt;/strong&gt; uniquely identifies every row in a table. No two rows can share the same value.&lt;/p&gt;

&lt;p&gt;In our &lt;code&gt;students&lt;/code&gt; table, &lt;code&gt;student_id&lt;/code&gt; is the primary key therefore every student gets a unique ID.&lt;/p&gt;

&lt;h3&gt;
  
  
  Foreign Keys
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Foreign Key (FK)&lt;/strong&gt; is a column in one table that points to the primary key of another table.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;enrollments&lt;/code&gt;, both &lt;code&gt;student_id&lt;/code&gt; and &lt;code&gt;course_id&lt;/code&gt; are foreign keys. They reference the &lt;code&gt;students&lt;/code&gt; and &lt;code&gt;courses&lt;/code&gt; tables respectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Matters
&lt;/h3&gt;

&lt;p&gt;Keys are what make relationships &lt;em&gt;real&lt;/em&gt; in a database. Without them, your tables are just isolated spreadsheets. With them, your database understands how data connects, and your queries can take advantage of that.&lt;/p&gt;




&lt;h2&gt;
  
  
  SQL Joins
&lt;/h2&gt;

&lt;p&gt;Now that our tables are related, &lt;strong&gt;Joins&lt;/strong&gt; are how we query across them.&lt;/p&gt;

&lt;p&gt;Let's use these sample tables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;students               enrollments            courses
-----------            -----------            -----------
1 | Alice              1 | 1 | 101            101 | Math
2 | Bob                2 | 1 | 102            102 | Physics
3 | Carol              3 | 2 | 101            103 | History
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  INNER JOIN
&lt;/h3&gt;

&lt;p&gt;Returns only rows where there's a match in &lt;strong&gt;both&lt;/strong&gt; tables.&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;-- Which courses is Alice enrolled in?&lt;/span&gt;
&lt;span class="k"&gt;SELECT&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&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;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt; &lt;span class="k"&gt;ON&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt;
&lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;course_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;course_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Alice'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Carol appears with NULL for course title — she exists but isn't enrolled yet.&lt;/p&gt;




&lt;h3&gt;
  
  
  RIGHT JOIN
&lt;/h3&gt;

&lt;p&gt;The opposite of LEFT JOIN, it returns &lt;strong&gt;all rows from the right table&lt;/strong&gt;, plus matches from the left.&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;-- Show all courses, even ones with no students enrolled&lt;/span&gt;
&lt;span class="k"&gt;SELECT&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&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;RIGHT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt; &lt;span class="k"&gt;ON&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt;
&lt;span class="k"&gt;RIGHT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;course_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;course_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; History (103) shows up with NULL for student name where the course exists but nobody enrolled.&lt;/p&gt;




&lt;h3&gt;
  
  
  FULL OUTER JOIN
&lt;/h3&gt;

&lt;p&gt;Returns &lt;strong&gt;everything&lt;/strong&gt; from both tables. NULLs fill in wherever there's no match.&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;students&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="n"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&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;FULL&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt; &lt;span class="k"&gt;ON&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="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;student_id&lt;/span&gt;
&lt;span class="k"&gt;FULL&lt;/span&gt; &lt;span class="k"&gt;OUTER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;enrollments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;course_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;courses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;course_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Every student and every course appears whether matched or not.&lt;/p&gt;




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

&lt;p&gt;Let's recap what we covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database relationships&lt;/strong&gt; prevent data duplication by linking tables instead of repeating data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-to-One&lt;/strong&gt;: one student, one profile&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One-to-Many&lt;/strong&gt;: one department, many students&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Many-to-Many&lt;/strong&gt;: students ↔ courses through an enrollments table&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Primary Keys&lt;/strong&gt; uniquely identify rows; &lt;strong&gt;Foreign Keys&lt;/strong&gt; point to another table's PK&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQL Joins&lt;/strong&gt; let you query across related tables ,INNER, LEFT, RIGHT, and FULL OUTER&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our university management system went from isolated tables to a fully connected, queryable database.&lt;/p&gt;

&lt;p&gt;That's the power of relational databases.&lt;/p&gt;

&lt;p&gt;If this helped, drop a comment or reaction below and let me know which SQL join trips you up the most! &lt;/p&gt;

</description>
      <category>database</category>
      <category>sqljoins</category>
      <category>powerfuldevs</category>
      <category>ai</category>
    </item>
    <item>
      <title>How Excel Is Used in Real-world Data Analysis</title>
      <dc:creator>Joy Mbugua</dc:creator>
      <pubDate>Sun, 07 Jun 2026 05:15:10 +0000</pubDate>
      <link>https://dev.to/joy_mbugua_f9c6ecc05289ef/how-excel-is-used-in-real-world-data-analysis-45de</link>
      <guid>https://dev.to/joy_mbugua_f9c6ecc05289ef/how-excel-is-used-in-real-world-data-analysis-45de</guid>
      <description>&lt;p&gt;When I started my Data Science and Analytics course a week ago, I expected to spend most of my time learning programming languages and building machine learning models.Instead one of the first tools we were introduced to was Microsoft Excel. At first, I wondered why a spreadsheet application was so important in a Data Science course, especially because I initially thought it was just something that accountants used. After just one week of learning it, I am starting to understand why.&lt;/p&gt;

&lt;p&gt;So, what even is Excel? At its core, it is a spreadsheet tool where you work with rows, columns, and cells to store and organize data. That is the simple version. But after one week, I am starting to see that it is also a place where raw, messy data can actually start to make sense, and also how that data is eventually used in decision-making &lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Uses I Did Not Know About
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1.Cleaning up messy data&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;One of the first things that surprised me was how much of data analysis is simply just fixing bad data. In real jobs, data comes in all shapes. Names typed in random cases, extra spaces everywhere, inconsistent formats. This week I learned &lt;code&gt;PROPER()&lt;/code&gt;, &lt;code&gt;UPPER()&lt;/code&gt;, and &lt;code&gt;LOWER()&lt;/code&gt;, and I immediately thought: this is literally what analysts do before anything else. They clean. Removing duplicates is another one that sounds boring but is actually critical because one duplicate record in a sales dataset can throw off an entire report.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.Tracking and summarizing numbers&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think about a small business owner who wants to know their average monthly sales, or a manager counting how many employees completed a training. Functions like &lt;code&gt;SUM()&lt;/code&gt;, &lt;code&gt;AVERAGE()&lt;/code&gt;, &lt;code&gt;COUNT()&lt;/code&gt;, &lt;code&gt;MAX()&lt;/code&gt;, and &lt;code&gt;MIN()&lt;/code&gt; handle all of that.&amp;nbsp; These functions seem simple at first glance but are actually very powerful when it comes to&amp;nbsp; summarizing information very quickly to be used for creating reports and identifying trends.&amp;nbsp; I practiced these on a sample dataset this week, that is the HR_dirty_data.xlsx dataset and it helped me understand the concepts even faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Filtering and validating data before analysis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sorting and filtering are things I had used before without thinking much about them. But now I understand why they matter. Before you analyze anything, you need to see the right slice of your data. Filtering lets you do that without deleting anything. I also learned about data validation this week, which is used to control what gets entered into a cell in the first place. That is something I had never thought about before, but it makes a lot of sense for keeping datasets consistent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Features That Stood Out to Me
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Conditional formatting&lt;/strong&gt; was probably my favorite discovery this week. You highlight cells based on their values, and suddenly a column of numbers becomes something you can read at a glance. I used it to flag values above a certain threshold and it felt genuinely useful, not just decorative.&lt;/p&gt;

&lt;p&gt;Another concept that changed the way I think about spreadsheets was &lt;strong&gt;cell references&lt;/strong&gt;. Rather than typing values directly into formulas, Excel allows you to reference cells so calculations update automatically whenever the underlying data changes.Here is an example i practiced:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;=AVERAGE(B2:B10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This formula calculates the average of the values between cells B2 and B10. What impressed me most was that if any of those values change, Excel automatically updates the result. That made me appreciate why analysts rely on cell references instead of manually recalculating everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Removing duplicates&lt;/strong&gt; was another one I underestimated. In the exercise we did, there were repeated customer entries in a list. Finding and removing them manually would have taken forever, but with Excel's Remove Duplicates feature, the repeated records were removed in seconds, leaving a cleaner and more reliable dataset for analysis.&lt;/p&gt;




&lt;h2&gt;
  
  
  How This Week Changed the Way I See Data
&lt;/h2&gt;

&lt;p&gt;Before this week, I thought data analysis was mainly about calculations and complex software. Now I realize that a large part of the process involves organizing, validating, and cleaning data before any analysis can happen.&lt;/p&gt;

&lt;p&gt;Learning Excel has shown me that sorting, filtering, formatting, and cleaning are not just preparation steps. They are essential parts of working with data effectively. Even after only one week, I can already see why Excel remains one of the most widely used tools in data analysis.&lt;/p&gt;

&lt;p&gt;I still have a lot to learn, but I am excited to continue building my skills and discovering how these foundations connect to more advanced areas of data science.&lt;/p&gt;

</description>
      <category>excel</category>
      <category>datascience</category>
      <category>beginners</category>
      <category>analytics</category>
    </item>
  </channel>
</rss>
