<?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: Mariam Turnesh</title>
    <description>The latest articles on Forem by Mariam Turnesh (@mariam_turnesh).</description>
    <link>https://forem.com/mariam_turnesh</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%2F3508352%2Fccfdd359-0c3e-4ee8-b73b-2264350da739.webp</url>
      <title>Forem: Mariam Turnesh</title>
      <link>https://forem.com/mariam_turnesh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mariam_turnesh"/>
    <language>en</language>
    <item>
      <title>How to connecting Power BI to SQL Database</title>
      <dc:creator>Mariam Turnesh</dc:creator>
      <pubDate>Sat, 04 Apr 2026 16:59:32 +0000</pubDate>
      <link>https://forem.com/mariam_turnesh/how-to-connecting-power-bi-to-sql-database-3ifc</link>
      <guid>https://forem.com/mariam_turnesh/how-to-connecting-power-bi-to-sql-database-3ifc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;At some point in your data journey, you build something in a database and realise that the people who actually need to use that data are managers, clients, the rest of the team who are never going to open a SQL editor. They need charts. They need something they can click through, filter, and read without writing a single query.&lt;br&gt;
That's where Power BI comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Power BI&lt;/strong&gt; is Microsoft's business intelligence and data visualisation tool. It takes data from various sources and turns it into interactive reports and dashboards, the kind that update automatically, respond to filters and can be shared across an entire organisation. Companies use it to track sales performance, monitor inventory, analyse customer behaviour, measure KPIs and make decisions based on what's actually happening in their data rather than what someone guesses is happening.&lt;/p&gt;

&lt;p&gt;But Power BI doesn't create data on its own. It connects to where the data already lives and more often than not, that place is a SQL database.&lt;br&gt;
SQL databases like PostgreSQL are built for exactly this kind of work. They store large volumes of structured data reliably, organise it into tables with clear relationships between them and allow multiple systems to read from and write to the same source at the same time. A business might have thousands of customer records, hundreds of thousands of transactions and a product catalogue that changes daily, all stored in one place, always current, always consistent.&lt;/p&gt;

&lt;p&gt;This is precisely why connecting Power BI to a SQL database matters so much. Instead of exporting data to a spreadsheet, building a chart, and then repeating the whole process when the data changes, a direct database connection means your reports are always reading from the live source. When the database updates, the dashboard reflects it ,no manual steps, no stale numbers.&lt;br&gt;
In this article, we'll walk through how to make that connection work: first with a local PostgreSQL database, then with a cloud-hosted one on Aiven.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 1 : Connecting Power BI to a Local PostgreSQL Database
&lt;/h2&gt;

&lt;p&gt;A local database is one running on your own computer. If you've been learning PostgreSQL and building databases on your machine, this is where you start.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 — Open Power BI and click Get Data
&lt;/h3&gt;

&lt;p&gt;Open Power BI Desktop and start with a blank report. On the &lt;strong&gt;Home&lt;/strong&gt; ribbon at the top, click &lt;strong&gt;Get Data&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.amazonaws.com%2Fuploads%2Farticles%2F9bormkqr210o6m6s9ir7.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%2F9bormkqr210o6m6s9ir7.png" alt=" " width="800" height="542"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Get Data is on the Home ribbon, that's your starting point for any connection&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 2 — Search for PostgreSQL
&lt;/h3&gt;

&lt;p&gt;A window pops up listing every data source Power BI can connect to, there are a lot of them. Don't scroll. Type &lt;strong&gt;PostgreSQL&lt;/strong&gt; in the search bar, select &lt;strong&gt;PostgreSQL Database&lt;/strong&gt; from the results, and click &lt;strong&gt;Connect&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.amazonaws.com%2Fuploads%2Farticles%2Fploon76qqngkx13t0g61.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%2Fploon76qqngkx13t0g61.png" alt=" " width="800" height="556"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Search saves you from scrolling through the entire list&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 3 — Enter your server and database details
&lt;/h3&gt;

&lt;p&gt;A connection dialog appears asking for two things: the server name and the database name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server:    localhost
Database:  assignment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;localhost&lt;/code&gt; tells Power BI that the database is on your own machine. The database name is whatever you named your database when you created it ,mine is &lt;code&gt;assignment&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Below that, you'll see a &lt;strong&gt;Data Connectivity mode&lt;/strong&gt; option with two choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Import&lt;/strong&gt; — Power BI copies the data into its own model. Faster to work with, great for most use cases.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DirectQuery&lt;/strong&gt; — Power BI queries the database live every time you interact with a report. Slower, but useful when you're working with very large or frequently-changing data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For most projects at this level, &lt;strong&gt;Import&lt;/strong&gt; is the right choice.&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%2Fhzihts9sbnv8l3xjgvxa.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%2Fhzihts9sbnv8l3xjgvxa.png" alt=" " width="800" height="536"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Enter localhost as the server, your database name, then choose Import&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 4 — Enter your credentials
&lt;/h3&gt;

&lt;p&gt;Power BI will ask for a username and password to authenticate. These are the same credentials you use when logging into pgAdmin, the PostgreSQL username (usually &lt;code&gt;postgres&lt;/code&gt;) and the password you set during installation.&lt;/p&gt;

&lt;p&gt;Enter them and click &lt;strong&gt;Connect&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.amazonaws.com%2Fuploads%2Farticles%2Fs8gyxxq24xgefsoshxv5.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%2Fs8gyxxq24xgefsoshxv5.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Use the same username and password you'd use in pgAdmin&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 5 — Select your tables and load
&lt;/h3&gt;

&lt;p&gt;Once connected, the &lt;strong&gt;Navigator&lt;/strong&gt; window opens. It shows every table in your database. Select the ones you want in my case, &lt;code&gt;customers&lt;/code&gt;, &lt;code&gt;products&lt;/code&gt;, &lt;code&gt;sales&lt;/code&gt; and &lt;code&gt;inventory&lt;/code&gt; and click &lt;strong&gt;Load&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Power BI imports them and they appear in the &lt;strong&gt;Data&lt;/strong&gt; pane on the right side of the screen. Your local connection is done.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 2 : Connecting Power BI to Aiven (Cloud PostgreSQL)
&lt;/h2&gt;

&lt;p&gt;Cloud databases work the same way in principle, but your connection details come from the cloud provider's dashboard rather than your local machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aiven&lt;/strong&gt; is a managed cloud database service, they host your PostgreSQL database on their infrastructure, so you don't have to worry about running it yourself. A lot of teams use this in production.&lt;/p&gt;
&lt;h3&gt;
  
  
  Step 1 — Get your connection details from Aiven
&lt;/h3&gt;

&lt;p&gt;Log into &lt;a href="https://console.aiven.io" rel="noopener noreferrer"&gt;console.aiven.io&lt;/a&gt;, open your PostgreSQL service, and go to the &lt;strong&gt;Overview&lt;/strong&gt; tab. You'll find everything you need listed there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Host&lt;/strong&gt; — the address of the server (a long &lt;code&gt;.aivencloud.com&lt;/code&gt; URL)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Port&lt;/strong&gt; — the port number Power BI will connect through&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database name&lt;/strong&gt; — for Aiven this is typically &lt;code&gt;defaultdb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Username&lt;/strong&gt; — &lt;code&gt;avnadmin&lt;/code&gt; by default&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password&lt;/strong&gt; — visible from the Overview tab&lt;/li&gt;
&lt;/ul&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%2Fmdmt5zdiekshlnup9f9q.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%2Fmdmt5zdiekshlnup9f9q.png" alt=" " width="800" height="342"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Everything you need for the connection lives on the Aiven Overview tab&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Keep this tab open you'll need to copy from it.&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 2 — Enter the connection details in Power BI
&lt;/h3&gt;

&lt;p&gt;Back in Power BI, go through the same flow: &lt;strong&gt;Get Data → PostgreSQL Database → Connect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In the connection dialog, enter your Aiven host in the &lt;strong&gt;Server&lt;/strong&gt; field and &lt;code&gt;defaultdb&lt;/code&gt; (or your database name) in the &lt;strong&gt;Database&lt;/strong&gt; field. Keep the mode on &lt;strong&gt;Import&lt;/strong&gt; and click &lt;strong&gt;OK&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.amazonaws.com%2Fuploads%2Farticles%2F2ngua1wpyicakyj01sak.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%2F2ngua1wpyicakyj01sak.png" alt=" " width="800" height="421"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Paste the host directly from the Aiven console, it's a long string, easy to mistype&lt;/em&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Step 3 — Enter your Aiven credentials
&lt;/h3&gt;

&lt;p&gt;When the credentials screen appears, enter &lt;code&gt;avnadmin&lt;/code&gt; as the username and the password from your Aiven Overview 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%2Fvipzae2lyl3fsosf51ji.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%2Fvipzae2lyl3fsosf51ji.png" alt=" " width="800" height="391"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Use the credentials exactly as shown in your Aiven console&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;Connect&lt;/strong&gt;. Power BI will authenticate and open the Navigator window, just like the local connection.&lt;/p&gt;


&lt;h3&gt;
  
  
  A note on SSL certificates
&lt;/h3&gt;

&lt;p&gt;Aiven requires all connections to be encrypted using &lt;strong&gt;SSL&lt;/strong&gt; (Secure Sockets Layer). SSL is a security protocol that encrypts the data travelling between your computer and the cloud server, so that even if someone intercepted it, they couldn't read it.&lt;/p&gt;

&lt;p&gt;When you connect Power BI to Aiven, it needs to verify that it's talking to a legitimate server, not something pretending to be one. That verification is done using a &lt;strong&gt;CA certificate&lt;/strong&gt; (Certificate Authority certificate), which you can download from your Aiven Overview tab.&lt;/p&gt;

&lt;p&gt;If Power BI rejects the connection with an SSL error, download the certificate from Aiven, rename it from &lt;code&gt;.pem&lt;/code&gt; to &lt;code&gt;.crt&lt;/code&gt;, and install it into your Windows Trusted Root Certification Authorities store. After a Power BI restart, the connection will go through. You only ever need to do this once per machine.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 3 :  Loading Tables and Building the Data Model
&lt;/h2&gt;

&lt;p&gt;Once you're connected whether locally or via Aiven the next steps are the same.&lt;/p&gt;
&lt;h3&gt;
  
  
  Loading your tables
&lt;/h3&gt;

&lt;p&gt;In the Navigator, select all the tables you need and click &lt;strong&gt;Load&lt;/strong&gt;. Power BI imports them and they show up in the Data pane on the right. You can click into any table to see its columns and values.&lt;/p&gt;


&lt;h3&gt;
  
  
  Setting up relationships in Model view
&lt;/h3&gt;

&lt;p&gt;Here's where a lot of beginners stop too early. Loading tables into Power BI is not the same as telling Power BI how those tables relate to each other. Without relationships, Power BI is just holding four separate spreadsheets, it can't combine them.&lt;/p&gt;

&lt;p&gt;Click the &lt;strong&gt;Model&lt;/strong&gt; icon on the left sidebar. You'll see your tables displayed as boxes, each showing their columns. This is where you define how they connect.&lt;/p&gt;

&lt;p&gt;For a retail database like mine, the relationships look like this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;From table&lt;/th&gt;
&lt;th&gt;To table&lt;/th&gt;
&lt;th&gt;Connecting column&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sales&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;customers&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;customer_id&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;sales&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;products&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;product_id&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;inventory&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;products&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;product_id&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;You can create these by dragging a column from one table onto the matching column in another. Power BI will often detect some relationships automatically, but always check them manually.&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%2Fhjztsz5652fmmaxoekb7.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%2Fhjztsz5652fmmaxoekb7.png" alt=" " width="800" height="413"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;The Model view shows how your tables link to each other the sales table sits at the centre&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Why this matters
&lt;/h3&gt;

&lt;p&gt;Once relationships are in place, Power BI knows how to cross-reference data across tables. If you build a chart showing total sales by customer name, Power BI can look up &lt;code&gt;customer_id&lt;/code&gt; in the &lt;code&gt;sales&lt;/code&gt; table, match it to the &lt;code&gt;customers&lt;/code&gt; table and pull the right name automatically, every time.&lt;/p&gt;

&lt;p&gt;Without the relationship, that lookup simply doesn't happen.&lt;/p&gt;

&lt;p&gt;This pattern one central &lt;strong&gt;fact table&lt;/strong&gt; (like &lt;code&gt;sales&lt;/code&gt;) connected to surrounding &lt;strong&gt;dimension tables&lt;/strong&gt; (like &lt;code&gt;customers&lt;/code&gt; and &lt;code&gt;products&lt;/code&gt;) is called a &lt;strong&gt;star schema&lt;/strong&gt;. It's the standard structure for analytical data models and the reason Power BI reports can filter and slice data so fluidly.&lt;/p&gt;


&lt;h2&gt;
  
  
  Part 4: Why SQL Skills Matter for Power BI Analysts
&lt;/h2&gt;

&lt;p&gt;Power BI is a capable tool, but there's something it can't do on its own: it can't make your data better than it arrives. Whatever goes into the model is what the dashboards are built on. If the data is messy, duplicated or incomplete when it lands in Power BI, the reports will reflect that and no amount of dragging visuals around will fix it.&lt;/p&gt;

&lt;p&gt;That's the first reason SQL matters. Before data even touches Power BI, an analyst with SQL skills can clean it, shape it and make sure only the right rows are coming through.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pulling only what you need&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Loading an entire table into Power BI when you only need six months of transactions is wasteful. It makes the model heavier and the report slower. SQL lets you filter at the source, before anything is imported:&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="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;assignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sales&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;sale_date&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="s1"&gt;'2023-01-01'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="s1"&gt;'2023-12-31'&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 a simple example, but in a real dataset with millions of rows, this kind of query is the difference between a report that loads in two seconds and one that takes twenty.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregating before loading&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Power BI can calculate totals and averages after data is loaded, but there are times when it makes more sense to do that work in SQL first. If a stakeholder only ever wants to see total sales per product, there's no reason to bring in every individual transaction:&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;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_amount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_sales&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;assignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sales&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="k"&gt;assignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;total_sales&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query does the heavy lifting in the database and hands Power BI one clean, summarised row per product. The model stays lean and the report stays fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Joining tables before they reach Power BI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;While Power BI has its own relationship system, there are cases where it makes more sense to join tables in SQL and load the result as a single, ready-to-use dataset. This is especially true when the logic behind the join is complex or when you want to be deliberate about which columns are exposed to the report layer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Catching problems before they become dashboard problems&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An analyst who knows SQL can inspect the data before loading it check for nulls, duplicates, unexpected values, mismatched IDs. These issues are much easier to handle in a SQL query than they are to track down after a dashboard is built and a stakeholder is asking why a number looks wrong.&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;-- Check for sales with no matching customer&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sale_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;assignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sales&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="k"&gt;assignment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This kind of query takes thirty seconds to write and can save hours of confusion later.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Using the Advanced Options SQL field in Power BI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When connecting to PostgreSQL, Power BI has an &lt;strong&gt;Advanced Options&lt;/strong&gt; section in the connection dialog that includes a SQL statement field. You can write a query there and Power BI will load the result instead of the full table. This gives you all the control of SQL with all the visualisation power of Power BI, working together from the start.&lt;/p&gt;

&lt;p&gt;The bottom line is this: Power BI tells the story. SQL decides which story is worth telling. Analysts who understand both are the ones who can build dashboards that people actually trust because they know what's in the data, not just what it looks like on a chart.&lt;/p&gt;




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

&lt;p&gt;Connecting Power BI to PostgreSQL is one of those things that seems technical until you do it once and then it becomes second nature. The local connection is a few clicks: &lt;code&gt;localhost&lt;/code&gt;, your database name, your pgAdmin credentials and you're in. The Aiven connection follows the same steps with a cloud host address instead.&lt;/p&gt;

&lt;p&gt;The part that actually requires thought is what comes after the connection. Getting relationships right in the model, making sure your tables are linked the way the data actually works, understanding why a star schema is the right structure that's where the analysis either holds up or falls apart.&lt;/p&gt;

&lt;p&gt;And underneath all of it is SQL. Not as a replacement for Power BI, but as the layer that makes everything Power BI receives worth working with. The best dashboards aren't built by people who are good at dragging visuals around. They're built by people who understood the data long before it reached the screen.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Something worked differently on your setup? Drop a comment below.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>powerbi</category>
      <category>beginners</category>
      <category>analytics</category>
    </item>
    <item>
      <title>SQL Joins and Window Functions</title>
      <dc:creator>Mariam Turnesh</dc:creator>
      <pubDate>Mon, 02 Mar 2026 20:08:34 +0000</pubDate>
      <link>https://forem.com/mariam_turnesh/sql-joins-and-window-functions-185h</link>
      <guid>https://forem.com/mariam_turnesh/sql-joins-and-window-functions-185h</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In relational databases, data is stored in separate tables to keep it organized, reduce duplication, and improve efficiency. For example, employee details might be stored in one table while department information is stored in another.&lt;/p&gt;

&lt;p&gt;When you need information from both tables at the same time, you use a JOIN. A JOIN combines rows from two tables using a related column, typically a primary key in one table and a foreign key in another. This relationship defines how the records are connected.&lt;/p&gt;

&lt;p&gt;The ON clause specifies the exact condition used to match rows between the tables. SQL evaluates this condition to determine which records relate to each other. The result is a single, combined dataset that brings together information that was originally stored separately.&lt;/p&gt;

&lt;p&gt;This guide walks through both Joins and Window Functions clearly, with examples you can follow from start to finish.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dataset
&lt;/h2&gt;

&lt;p&gt;We will use two tables throughout this entire article so the examples stay consistent and easy to follow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;customer_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="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="n"&gt;country&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;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;customers&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;'Alice'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Mensah'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Kenya'&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;'Okonkwo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'Nigeria'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Carol'&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;'Kenya'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Diana'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Asante'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Ghana'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Edward'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'Kimani'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Kenya'&lt;/span&gt;&lt;span class="p"&gt;);&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;orders&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;order_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;customer_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;product&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;amount&lt;/span&gt;       &lt;span class="nb"&gt;DECIMAL&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;order_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;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;orders&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;101&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;'Laptop'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-01-10'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;102&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;'Mouse'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-02-14'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;103&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Keyboard'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-03-01'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;104&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;'Monitor'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-03-15'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;105&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Headphones'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-04-02'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;customer_id = 6&lt;/code&gt; in the orders table has no matching customer. Diana (customer_id = 4) and Edward (customer_id = 5) have never placed an order. These details will matter as we go through each join type.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  A Quick Note on Aliases
&lt;/h3&gt;

&lt;p&gt;You will notice queries using short names like &lt;code&gt;c&lt;/code&gt; and &lt;code&gt;o&lt;/code&gt; instead of the full table name. These are called &lt;strong&gt;aliases&lt;/strong&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;-- Without aliases&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;customers&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="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&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;orders&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- With aliases — same result, much cleaner&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&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;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You assign an alias by writing a short name right after the table name in the &lt;code&gt;FROM&lt;/code&gt; or &lt;code&gt;JOIN&lt;/code&gt; clause. Aliases are especially useful when table names are long or when the same table appears more than once in a query. Every example from here on uses them.&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1 — SQL Joins
&lt;/h2&gt;

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

&lt;p&gt;Returns only the rows where a match exists in &lt;strong&gt;both&lt;/strong&gt; tables. Rows with no match on either side are excluded.&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="k"&gt;c&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="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;order_date&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&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;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;first_name&lt;/th&gt;
&lt;th&gt;last_name&lt;/th&gt;
&lt;th&gt;product&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;th&gt;order_date&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mensah&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;900.00&lt;/td&gt;
&lt;td&gt;2024-01-10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mensah&lt;/td&gt;
&lt;td&gt;Mouse&lt;/td&gt;
&lt;td&gt;25.00&lt;/td&gt;
&lt;td&gt;2024-02-14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Okonkwo&lt;/td&gt;
&lt;td&gt;Monitor&lt;/td&gt;
&lt;td&gt;300.00&lt;/td&gt;
&lt;td&gt;2024-03-15&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Wanjiku&lt;/td&gt;
&lt;td&gt;Keyboard&lt;/td&gt;
&lt;td&gt;75.00&lt;/td&gt;
&lt;td&gt;2024-03-01&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Alice, Brian and Carol matched so they appear. Diana and Edward have no orders so they are excluded. Order 105 (customer_id = 6) has no matching customer so it is also excluded.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. LEFT JOIN
&lt;/h3&gt;

&lt;p&gt;Returns &lt;strong&gt;all rows from the left table&lt;/strong&gt; and matching rows from the right. Where there is no match, the right-side columns return &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The "left" table is whichever comes after &lt;code&gt;FROM&lt;/code&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="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&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="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;first_name&lt;/th&gt;
&lt;th&gt;last_name&lt;/th&gt;
&lt;th&gt;product&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mensah&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;900.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mensah&lt;/td&gt;
&lt;td&gt;Mouse&lt;/td&gt;
&lt;td&gt;25.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Okonkwo&lt;/td&gt;
&lt;td&gt;Monitor&lt;/td&gt;
&lt;td&gt;300.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Wanjiku&lt;/td&gt;
&lt;td&gt;Keyboard&lt;/td&gt;
&lt;td&gt;75.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;Asante&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edward&lt;/td&gt;
&lt;td&gt;Kimani&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All five customers appear. Diana and Edward have no orders so their product and amount columns are &lt;code&gt;NULL&lt;/code&gt;. Order 105 is still excluded because it has no matching customer in the left table.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The LEFT JOIN is also known as the LEFT OUTER JOIN.&lt;/em&gt;&lt;/p&gt;




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

&lt;p&gt;Returns &lt;strong&gt;all rows from the right table&lt;/strong&gt; and matching rows from the left. Where there is no match, the left-side columns return &lt;code&gt;NULL&lt;/code&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="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&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="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&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;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;first_name&lt;/th&gt;
&lt;th&gt;last_name&lt;/th&gt;
&lt;th&gt;product&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mensah&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;900.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mensah&lt;/td&gt;
&lt;td&gt;Mouse&lt;/td&gt;
&lt;td&gt;25.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Okonkwo&lt;/td&gt;
&lt;td&gt;Monitor&lt;/td&gt;
&lt;td&gt;300.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Wanjiku&lt;/td&gt;
&lt;td&gt;Keyboard&lt;/td&gt;
&lt;td&gt;75.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;Headphones&lt;/td&gt;
&lt;td&gt;120.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;All five orders appear. Order 105 (Headphones) has no matching customer so &lt;code&gt;first_name&lt;/code&gt; and &lt;code&gt;last_name&lt;/code&gt; are &lt;code&gt;NULL&lt;/code&gt;. Diana and Edward are gone because they live in the left table and have no matching order.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The RIGHT JOIN is also known as the RIGHT OUTER JOIN.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 Most developers rewrite &lt;code&gt;RIGHT JOIN&lt;/code&gt; as a &lt;code&gt;LEFT JOIN&lt;/code&gt; by swapping the table order as it reads more naturally. These two queries return identical results:&lt;/p&gt;


&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- As RIGHT JOIN&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&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;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Same result as LEFT JOIN (tables swapped)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;




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

&lt;p&gt;Returns &lt;strong&gt;all rows from both tables&lt;/strong&gt;. Where there is no match on either side, &lt;code&gt;NULL&lt;/code&gt; fills in the gap. No row from either table is left out.&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="k"&gt;c&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="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;amount&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&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;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;first_name&lt;/th&gt;
&lt;th&gt;last_name&lt;/th&gt;
&lt;th&gt;product&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mensah&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;td&gt;900.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mensah&lt;/td&gt;
&lt;td&gt;Mouse&lt;/td&gt;
&lt;td&gt;25.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Okonkwo&lt;/td&gt;
&lt;td&gt;Monitor&lt;/td&gt;
&lt;td&gt;300.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Wanjiku&lt;/td&gt;
&lt;td&gt;Keyboard&lt;/td&gt;
&lt;td&gt;75.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;Asante&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edward&lt;/td&gt;
&lt;td&gt;Kimani&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;Headphones&lt;/td&gt;
&lt;td&gt;120.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every customer and every order appears, matched or not.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;strong&gt;MySQL does not support &lt;code&gt;FULL OUTER JOIN&lt;/code&gt;.&lt;/strong&gt; Use a &lt;code&gt;UNION&lt;/code&gt; to emulate it:&lt;/p&gt;


&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;
&lt;span class="k"&gt;UNION&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&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;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  5. SELF JOIN
&lt;/h3&gt;

&lt;p&gt;A SELF JOIN joins a table &lt;strong&gt;to itself&lt;/strong&gt;. It is used when rows in a table relate to other rows in the same table. The most common example is an employee table where each employee has a &lt;code&gt;manager_id&lt;/code&gt; that points to another employee in the same table.&lt;/p&gt;

&lt;p&gt;We will use a separate employees table for this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;emp_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;manager_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;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;employees&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;'Alice'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;3&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Carol'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Diana'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alice and Brian report to Carol (emp_id = 3). Carol reports to Diana (emp_id = 4). Diana is at the top so she has no manager.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;manager&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;manager_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;emp_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;employee&lt;/th&gt;
&lt;th&gt;manager&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice the aliases &lt;code&gt;e&lt;/code&gt; and &lt;code&gt;m&lt;/code&gt;. Because we are joining the employees table to itself, aliases are what tell SQL which copy of the table is which. Without them the query would be ambiguous and SQL would not know which &lt;code&gt;name&lt;/code&gt; column to use. Diana returns &lt;code&gt;NULL&lt;/code&gt; because she has no manager.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. CROSS JOIN
&lt;/h3&gt;

&lt;p&gt;A CROSS JOIN returns every possible combination of rows from both tables. There is no &lt;code&gt;ON&lt;/code&gt; clause because you are not matching rows, you are pairing every row from one table with every row from the other.&lt;/p&gt;

&lt;p&gt;Using our existing 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="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;c&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="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With 5 customers and 5 orders, the result has 5 x 5 = &lt;strong&gt;25 rows&lt;/strong&gt;. Every customer is paired with every product regardless of whether they ordered it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;first_name&lt;/th&gt;
&lt;th&gt;product&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Mouse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Keyboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Monitor&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Headphones&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Laptop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Mouse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is useful for generating all possible combinations such as product variants, scheduling slots, or test data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ On large tables, CROSS JOIN grows very fast. Two tables with 1,000 rows each produce 1,000,000 rows.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  Join Types Summary
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Join&lt;/th&gt;
&lt;th&gt;What It Returns&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;INNER JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Only rows with a match in both tables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LEFT JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All rows from the left table + matching rows from the right&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RIGHT JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All rows from the right table + matching rows from the left&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FULL OUTER JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;All rows from both tables&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;SELF JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A table joined to itself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CROSS JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Every possible combination of rows from both tables&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Part 2 — Window Functions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Are Window Functions?
&lt;/h3&gt;

&lt;p&gt;Window functions perform calculations across a set of rows &lt;strong&gt;without collapsing them&lt;/strong&gt;. That is what separates them from regular aggregate functions.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;GROUP BY&lt;/code&gt;, every group gets summarised into a single row. With window functions, every row stays in the result and the calculation is added as an extra column alongside it.&lt;/p&gt;

&lt;p&gt;They operate over a &lt;strong&gt;window&lt;/strong&gt; of rows defined by the &lt;code&gt;OVER()&lt;/code&gt; clause.&lt;/p&gt;




&lt;h3&gt;
  
  
  Syntax
&lt;/h3&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="k"&gt;column_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
           &lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;partition_column&lt;/span&gt;
           &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt;     &lt;span class="n"&gt;order_column&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;output_column&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Part&lt;/th&gt;
&lt;th&gt;What It Does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;function()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The window function e.g. &lt;code&gt;RANK()&lt;/code&gt;, &lt;code&gt;SUM()&lt;/code&gt;, &lt;code&gt;LAG()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;OVER()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tells SQL this is a window function and defines the window&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;PARTITION BY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Divides rows into independent groups. The function restarts for each group&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ORDER BY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines the order of rows within each partition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;AS output_column&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Names the result column&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Window functions run after &lt;code&gt;WHERE&lt;/code&gt;, &lt;code&gt;GROUP BY&lt;/code&gt;, and &lt;code&gt;HAVING&lt;/code&gt;, so you cannot filter on a window function directly in a &lt;code&gt;WHERE&lt;/code&gt; clause. Wrap it in a CTE or subquery instead.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;For the window function examples we will use this employees 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;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;emp_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;department&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="n"&gt;salary&lt;/span&gt;      &lt;span class="nb"&gt;DECIMAL&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;employees&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;'Alice'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Engineering'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;72000&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;'Marketing'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mi"&gt;58000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Carol'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Engineering'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;65000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Diana'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Marketing'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="mi"&gt;71000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Edward'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'Finance'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="mi"&gt;91000&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Faith'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="s1"&gt;'Engineering'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;72000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Types of Window Functions
&lt;/h3&gt;

&lt;p&gt;Window functions fall into three categories:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Aggregate:&lt;/strong&gt; &lt;code&gt;SUM()&lt;/code&gt;, &lt;code&gt;AVG()&lt;/code&gt;, &lt;code&gt;COUNT()&lt;/code&gt;, &lt;code&gt;MIN()&lt;/code&gt;, &lt;code&gt;MAX()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ranking:&lt;/strong&gt; &lt;code&gt;ROW_NUMBER()&lt;/code&gt;, &lt;code&gt;RANK()&lt;/code&gt;, &lt;code&gt;DENSE_RANK()&lt;/code&gt;, &lt;code&gt;PERCENT_RANK()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Value:&lt;/strong&gt; &lt;code&gt;LAG()&lt;/code&gt;, &lt;code&gt;LEAD()&lt;/code&gt;, &lt;code&gt;FIRST_VALUE()&lt;/code&gt;, &lt;code&gt;LAST_VALUE()&lt;/code&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  1. ROW_NUMBER()
&lt;/h3&gt;

&lt;p&gt;Assigns a unique sequential number to each row within a partition, ordered by the column you specify.&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="k"&gt;DESC&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;row_num&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;department&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;th&gt;row_num&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faith&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;65000.00&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;71000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;58000.00&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edward&lt;/td&gt;
&lt;td&gt;Finance&lt;/td&gt;
&lt;td&gt;91000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The numbering restarts for each department because of &lt;code&gt;PARTITION BY department&lt;/code&gt;. Alice and Faith earn the same salary but still get different row numbers because &lt;code&gt;ROW_NUMBER&lt;/code&gt; is always unique.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. RANK()
&lt;/h3&gt;

&lt;p&gt;Assigns ranks within a partition. When rows tie, they receive the same rank and the next rank skips to account for the tie.&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;RANK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="k"&gt;DESC&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;rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;department&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;th&gt;rank&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faith&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;65000.00&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;71000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;58000.00&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edward&lt;/td&gt;
&lt;td&gt;Finance&lt;/td&gt;
&lt;td&gt;91000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Alice and Faith both earn 72,000 so they both get rank 1. The next rank jumps to 3 because rank 2 is skipped to account for the tie.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. DENSE_RANK()
&lt;/h3&gt;

&lt;p&gt;Works like &lt;code&gt;RANK()&lt;/code&gt; but without the gaps. Tied rows share the same rank and the next rank continues without skipping.&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;DENSE_RANK&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="k"&gt;DESC&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;dense_rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;department&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;th&gt;dense_rank&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faith&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;65000.00&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;71000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;58000.00&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edward&lt;/td&gt;
&lt;td&gt;Finance&lt;/td&gt;
&lt;td&gt;91000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Alice and Faith are still both rank 1 but now Carol is rank 2 not 3. No numbers are skipped.&lt;/p&gt;




&lt;h3&gt;
  
  
  Comparing ROW_NUMBER, RANK, and DENSE_RANK
&lt;/h3&gt;

&lt;p&gt;Using the Engineering department where Alice and Faith both earn 72,000:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;th&gt;ROW_NUMBER&lt;/th&gt;
&lt;th&gt;RANK&lt;/th&gt;
&lt;th&gt;DENSE_RANK&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faith&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;65000.00&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ROW_NUMBER&lt;/strong&gt; always unique, no ties recognised&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RANK&lt;/strong&gt; ties get the same rank, next rank skips&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DENSE_RANK&lt;/strong&gt; ties get the same rank, next rank does not skip&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  4. SUM() — Running Total
&lt;/h3&gt;

&lt;p&gt;When you use &lt;code&gt;SUM()&lt;/code&gt; as a window function with &lt;code&gt;ORDER BY&lt;/code&gt;, it accumulates a running total as it moves down the rows.&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
           &lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;
           &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;emp_id&lt;/span&gt;
           &lt;span class="k"&gt;ROWS&lt;/span&gt; &lt;span class="k"&gt;BETWEEN&lt;/span&gt; &lt;span class="n"&gt;UNBOUNDED&lt;/span&gt; &lt;span class="k"&gt;PRECEDING&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;CURRENT&lt;/span&gt; &lt;span class="k"&gt;ROW&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;running_total&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;department&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;th&gt;running_total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;65000.00&lt;/td&gt;
&lt;td&gt;137000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faith&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;209000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;58000.00&lt;/td&gt;
&lt;td&gt;58000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;71000.00&lt;/td&gt;
&lt;td&gt;129000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edward&lt;/td&gt;
&lt;td&gt;Finance&lt;/td&gt;
&lt;td&gt;91000.00&lt;/td&gt;
&lt;td&gt;91000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW&lt;/code&gt; tells SQL to include every row from the start of the partition up to the current row. The total resets for each department because of &lt;code&gt;PARTITION BY&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  5. AVG() — Department Average Per Row
&lt;/h3&gt;

&lt;p&gt;Without &lt;code&gt;ORDER BY&lt;/code&gt;, a window aggregate runs across the entire partition at once, giving you the group value on every individual row.&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;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;dept_avg&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;department&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;th&gt;dept_avg&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;69666.67&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Carol&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;65000.00&lt;/td&gt;
&lt;td&gt;69666.67&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faith&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;td&gt;69666.67&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;58000.00&lt;/td&gt;
&lt;td&gt;64500.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;71000.00&lt;/td&gt;
&lt;td&gt;64500.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edward&lt;/td&gt;
&lt;td&gt;Finance&lt;/td&gt;
&lt;td&gt;91000.00&lt;/td&gt;
&lt;td&gt;91000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Every employee keeps their individual row and the department average sits right next to their salary. This is the query that &lt;code&gt;GROUP BY&lt;/code&gt; simply cannot do.&lt;/p&gt;




&lt;h3&gt;
  
  
  6. LAG() and LEAD()
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;LAG()&lt;/code&gt; looks back at the value of a previous row. &lt;code&gt;LEAD()&lt;/code&gt; looks ahead at the value of a future row. Both are used for period-over-period comparisons.&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;order_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;LAG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&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;OVER&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="n"&gt;order_date&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;prev_order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;LEAD&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;amount&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;OVER&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="n"&gt;order_date&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;next_order&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;order_date&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;th&gt;prev_order&lt;/th&gt;
&lt;th&gt;next_order&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2024-01-10&lt;/td&gt;
&lt;td&gt;900.00&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;25.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2024-02-14&lt;/td&gt;
&lt;td&gt;25.00&lt;/td&gt;
&lt;td&gt;900.00&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The first row returns &lt;code&gt;NULL&lt;/code&gt; for &lt;code&gt;LAG&lt;/code&gt; because there is no row before it. The last row returns &lt;code&gt;NULL&lt;/code&gt; for &lt;code&gt;LEAD&lt;/code&gt; because there is no row after it. This is expected behaviour, not an error.&lt;/p&gt;




&lt;h3&gt;
  
  
  Getting the Top Earner Per Department
&lt;/h3&gt;

&lt;p&gt;This is one of the most common window function patterns. It requires a CTE because you cannot filter on a window function in a &lt;code&gt;WHERE&lt;/code&gt; clause directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;ranked&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&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;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="n"&gt;ROW_NUMBER&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="n"&gt;OVER&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;PARTITION&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="k"&gt;DESC&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;rn&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&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;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;ranked&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;rn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;name&lt;/th&gt;
&lt;th&gt;department&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Alice&lt;/td&gt;
&lt;td&gt;Engineering&lt;/td&gt;
&lt;td&gt;72000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Diana&lt;/td&gt;
&lt;td&gt;Marketing&lt;/td&gt;
&lt;td&gt;71000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edward&lt;/td&gt;
&lt;td&gt;Finance&lt;/td&gt;
&lt;td&gt;91000.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We use &lt;code&gt;ROW_NUMBER()&lt;/code&gt; here instead of &lt;code&gt;RANK()&lt;/code&gt; so that ties produce exactly one result per department. The CTE materialises the window function result first and then the outer &lt;code&gt;WHERE&lt;/code&gt; filters on it.&lt;/p&gt;




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

&lt;p&gt;Joins connect data that lives in separate tables. The join type you pick decides what happens to rows with no match. &lt;code&gt;INNER JOIN&lt;/code&gt; drops them, &lt;code&gt;LEFT JOIN&lt;/code&gt; keeps the left side, &lt;code&gt;FULL OUTER JOIN&lt;/code&gt; keeps everything.&lt;/p&gt;

&lt;p&gt;Window Functions bring group-level calculations down to the row level without losing any individual rows. &lt;code&gt;PARTITION BY&lt;/code&gt; creates the groups, &lt;code&gt;ORDER BY&lt;/code&gt; inside &lt;code&gt;OVER()&lt;/code&gt; controls the order within them, and functions like &lt;code&gt;RANK()&lt;/code&gt;, &lt;code&gt;SUM()&lt;/code&gt;, and &lt;code&gt;LAG()&lt;/code&gt; do the work.&lt;/p&gt;

&lt;p&gt;Master these two and most real-world SQL analysis becomes a lot more straightforward.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have a question about a specific join or function? Drop it in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>beginners</category>
      <category>database</category>
      <category>dataanlysis</category>
    </item>
    <item>
      <title>How Analysts Turn Messy Data into Action Using Power BI</title>
      <dc:creator>Mariam Turnesh</dc:creator>
      <pubDate>Fri, 06 Feb 2026 14:39:31 +0000</pubDate>
      <link>https://forem.com/mariam_turnesh/how-analysts-turn-chaos-into-clarity-my-real-journey-through-power-bi-1o3a</link>
      <guid>https://forem.com/mariam_turnesh/how-analysts-turn-chaos-into-clarity-my-real-journey-through-power-bi-1o3a</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When I first started learning Power BI, I thought data analysis was mostly about building charts and dashboards.&lt;br&gt;
I was wrong.&lt;br&gt;
What I quickly realized is that most of the work happens before the visuals. Real-world data is messy, inconsistent and often confusing and Power BI is only powerful when you know how to translate that mess into something meaningful.&lt;/p&gt;

&lt;p&gt;This article explains how analysts (especially beginners like me) use Power BI to move from messy data, through DAX and finally into dashboards that actually drive action.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Reality Check Nobody Prepared Me For&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;You open that CSV file or connect to that database feeling optimistic. You're ready to build some dashboards, create insights, change the world. Then you see it: dates formatted as text, customer names spelled seventeen different ways, empty cells scattered around like landmines, numbers mixed with currency symbols, and columns labeled "Field_47" with zero documentation.&lt;/p&gt;

&lt;p&gt;My first real dataset had all of this plus duplicate records of the same transactions. I remember staring at it thinking, "Did I get bad data? Should I ask for a cleaner version?"&lt;/p&gt;

&lt;p&gt;Then I learned the truth: &lt;strong&gt;this is normal. This is the job.&lt;/strong&gt; Messy data isn't bad data,it's just raw. And if you can't translate raw data into something usable, none of the fancy dashboard skills matter.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;What You're Actually Looking For (And Why It Matters)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When I first crack open a messy dataset, I'm hunting for specific problems. Here's what trips up most analyses before they even start:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inconsistent Formatting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This drives me nuts but it's everywhere. You'll have one column with "New York," "NY," "new york," and "N.Y." all meaning the same thing. Power BI doesn't know they're the same, so your visuals will treat them as four separate categories. Your boss asks why sales are split across four different locations and you look like you don't know what you're doing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Missing Values&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are trickier than they seem. Sometimes a blank means "we don't know." Sometimes it means "zero." Sometimes it means "this doesn't apply." You have to figure out which one it is, because filling in blanks with zeros when they actually mean "unknown" will completely screw up your averages and totals. &lt;/p&gt;

&lt;p&gt;I learned this the hard way when my average order value calculation was totally wrong because I'd replaced nulls with zeros.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Types That Make No Sense&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a constant headache. Dates stored as text, numbers stored as text, percentages stored as whole numbers (so 85% shows up as 85.00 instead of 0.85). Power Query's type detection helps, but you can't just trust it blindly. &lt;/p&gt;

&lt;p&gt;I once built an entire time series analysis before realizing my dates were still text and none of my date hierarchies worked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Duplicate Records&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These happen more than you'd think. Maybe the same transaction got logged twice. Maybe someone entered the same customer with slightly different info. You need to spot these and decide whether to keep both records, merge them or delete the duplicates entirely.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;This step completely changed how I viewed data analysis.&lt;/strong&gt; Instead of rushing to build visuals, I learned to slow down and ask: &lt;em&gt;Can this data be trusted?&lt;/em&gt; If the answer is no, everything that follows becomes unreliable.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Power Query: Where the Translation Actually Happens
&lt;/h2&gt;

&lt;p&gt;In Power BI, the translation process starts in &lt;strong&gt;Power Query&lt;/strong&gt;. This is where analysts prepare data so Power BI can analyze it correctly.&lt;/p&gt;

&lt;p&gt;Here's my actual workflow when I'm cleaning data:&lt;/p&gt;

&lt;p&gt;First, I use Power Query to get a feel for what I'm working with. I turn on the column quality, column distribution and column profile options. These show you at a glance how many nulls you have, how many distinct values, whether you have outliers. It's like getting an X-ray of your data before you operate on it.&lt;/p&gt;

&lt;p&gt;Then I start fixing things systematically:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Standardizing text&lt;/strong&gt; - I use TRIM and CLEAN to get rid of weird spacing. I use Replace Values for common inconsistencies. For the "New York" problem I mentioned earlier, I create a conditional column or use Replace Values to make everything consistent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixing data types&lt;/strong&gt; - I manually set every single column type because auto-detect has burned me too many times. Date/Time for dates, Decimal Number for currency, Whole Number for counts, Text for IDs (even if they look like numbers trust me on this one).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Handling missing data intentionally&lt;/strong&gt; - Sometimes I filter out incomplete rows. Sometimes I replace nulls with "Unknown" or "Not Provided" for categorical data. For numbers, it depends on context, sometimes zero makes sense, sometimes you need to leave it null, sometimes you calculate an average to fill it in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Removing junk&lt;/strong&gt; - Duplicate records go away. Irrelevant columns get deleted. Rows that are clearly data entry errors get filtered out (like that one time I found a customer age of 247).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Splitting and combining&lt;/strong&gt; - I split columns so each one represents a single piece of information. A "Full Name" column becomes "First Name" and "Last Name." A messy address becomes separate fields for street, city, state, zip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Renaming everything&lt;/strong&gt; - I rename columns to clearly describe what they contain. "Col_17" becomes "Customer_Acquisition_Date." Future me always thanks past me for this.&lt;/p&gt;

&lt;p&gt;This is where you earn your money as an analyst. Nobody sees this work, but it's the foundation of everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  Data Modeling: Teaching Power BI How Things Connect
&lt;/h2&gt;

&lt;p&gt;Once the data is clean, the next challenge is structuring it properly. Power BI doesn't just display tables, it uses relationships between them to filter and calculate data correctly.&lt;/p&gt;

&lt;p&gt;As a beginner, the biggest concept I learned was the difference between &lt;strong&gt;fact tables&lt;/strong&gt; and &lt;strong&gt;dimension tables&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fact tables:&lt;/strong&gt; Store what actually happened; sales transactions, website visits or support tickets. Each row represents an event, which is why these tables usually have a lot of rows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dimension tables:&lt;/strong&gt; Provide context around those events. They describe customers, products, dates or locations. Instead of growing longer, these tables tend to grow wider, with more descriptive columns.&lt;/p&gt;

&lt;p&gt;By connecting these tables using clear one-to-many relationships (one customer can have many sales, one product can appear in many transactions), Power BI can filter visuals correctly, respond properly to slicers, and produce accurate aggregations.&lt;/p&gt;

&lt;p&gt;Honestly, I didn’t get why this mattered at first. Then I built a dashboard without proper relationships. Someone clicked a region slicer, half the visuals updated, half didn’t and the numbers were all over the place. Lesson learned.&lt;/p&gt;

&lt;p&gt;A good data model doesn't look exciting, but it makes dashboards behave the way users expect. Without it, even clean data produces confusing results.&lt;/p&gt;




&lt;h2&gt;
  
  
  DAX: Defining What Numbers Actually Mean
&lt;/h2&gt;

&lt;p&gt;DAX was the part I found most intimidating at first. All those functions and syntax rules felt like learning a new programming language.&lt;/p&gt;

&lt;p&gt;But over time, I realized that &lt;strong&gt;DAX isn't just about formulas,it's about defining meaning.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of asking "How do I write this formula?", analysts ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What exactly does "total sales" mean for our business?&lt;/li&gt;
&lt;li&gt;Should it include returns? Discounts? Tax?&lt;/li&gt;
&lt;li&gt;How should this number change when someone filters by date or region?&lt;/li&gt;
&lt;li&gt;How do we compare current results to last year's performance?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using DAX measures, Power BI allows calculations to adapt dynamically to filters, dates and user interaction. This is what transforms static numbers into insights.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A simple example:&lt;/strong&gt; when I create a measure for Total Revenue, it's not just &lt;code&gt;SUM(Sales[Amount])&lt;/code&gt;. I have to think about whether cancelled orders should be excluded. Whether I need to account for currency conversion. Whether partial refunds affect the number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DAX is the bridge between raw numbers and real business questions.&lt;/strong&gt; It's where you translate data into the language your stakeholders actually care about.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stuff That's Hard to Learn From Tutorials
&lt;/h2&gt;

&lt;p&gt;Here's what trips people up: knowing when to clean in Power Query versus when to handle it in DAX measures.&lt;/p&gt;

&lt;p&gt;Generally, if it's structural (fixing data types, removing duplicates, standardizing categories), do it in &lt;strong&gt;Power Query&lt;/strong&gt;. If it's calculation-based (like handling division by zero in a ratio, or computing year-over-year growth), do it in &lt;strong&gt;DAX&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Why? Power Query transformations happen once when you refresh your data. DAX calculations happen every time someone interacts with your report. If you try to do heavy transformations in DAX, your dashboards will be slow and painful to use.&lt;/p&gt;

&lt;p&gt;Another thing &lt;strong&gt;documentation is not optional.&lt;/strong&gt; When I create a Power BI file, I keep notes about what I cleaned and why. Months later when someone asks why you excluded certain records or how you defined "active customer," you need to have an answer. I use the Description field in Power Query steps and add comments to complex DAX measures.&lt;/p&gt;

&lt;p&gt;Also, always keep a copy of your original raw data. Never overwrite source files. I learned this the hard way when I spent a day cleaning a dataset, saved over the original, then realized I'd filtered out records I actually needed.&lt;/p&gt;




&lt;h2&gt;
  
  
  Dashboards: When Translation Finally Becomes Visible
&lt;/h2&gt;

&lt;p&gt;Only after data is cleaned, modeled and measured does the dashboard truly matter.&lt;/p&gt;

&lt;p&gt;Here's what I learned about dashboards: &lt;strong&gt;they're not meant to show everything,they're meant to guide attention.&lt;/strong&gt; Early on, I tried cramming every possible metric onto one page. It looked impressive to me but confused everyone else.&lt;/p&gt;

&lt;p&gt;Effective Power BI dashboards do a few things really well:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;They highlight key metrics&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Using KPI cards or scorecards. The three or four numbers that actually matter get prominent placement. Everything else is secondary.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;They show trends instead of isolated values&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A single number like "450 sales this month" means nothing without context. But a line chart showing whether that's up or down from last month? That tells a story.&lt;/p&gt;

&lt;h3&gt;
  
  
  They allow exploration through slicers and filters
&lt;/h3&gt;

&lt;p&gt;Users can slice by date, region, product category, whatever makes sense. This turns a static report into an interactive tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  They keep layouts simple and focused
&lt;/h3&gt;

&lt;p&gt;White space is your friend. Clear labels matter more than fancy visuals. If someone has to squint or ask what they're looking at, you've failed.&lt;/p&gt;

&lt;p&gt;When dashboards are designed well, decision-makers don't need to ask for new reports. They can explore the data themselves and act immediately. &lt;strong&gt;That's when analysis turns into action.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Success Actually Looks Like
&lt;/h2&gt;

&lt;p&gt;You know you've translated your messy data successfully when you can build a visual and it just works. You don't have to keep going back to Power Query to fix "one more thing." Your slicers show the categories you expect. Your date hierarchies make sense. Your totals actually total correctly.&lt;/p&gt;

&lt;p&gt;The goal isn't perfection, there's always another tweak you could make. The goal is reliable data that answers business questions without creating new confusion.&lt;/p&gt;

&lt;p&gt;That's what this whole job is about, really. Taking information that's scattered and inconsistent and broken and turning it into something someone can actually use to make a decision. &lt;/p&gt;

&lt;p&gt;The dashboards and visualizations are just the final 10% that everyone sees. The real work happens in Power Query, in those transformation steps nobody ever asks about.&lt;/p&gt;




&lt;h2&gt;
  
  
  From Learning Power BI to Actually Thinking Like an Analyst
&lt;/h2&gt;

&lt;p&gt;Learning Power BI taught me something important: &lt;strong&gt;data analysis is not about tools,it's about thinking.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Power BI simply provides the environment where analysts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Translate messy data using Power Query&lt;/li&gt;
&lt;li&gt;Structure it with proper modeling&lt;/li&gt;
&lt;li&gt;Define meaning using DAX&lt;/li&gt;
&lt;li&gt;Communicate insights through dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once I understood this workflow, Power BI stopped feeling overwhelming and started making sense. The tool just facilitates the process. The real skill is knowing what questions to ask at each stage.&lt;/p&gt;

&lt;p&gt;If you're just starting out, focus less on perfect visuals and more on understanding this process. Master the unglamorous parts first:the data cleaning, the relationships, the proper data types. Everything else becomes easier once the foundation is right.&lt;/p&gt;

&lt;p&gt;And honestly? Once you get good at this part, the actual analysis becomes almost fun. Because you're working with data you trust, data you understand, data that's finally ready to tell you something true.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you're learning Power BI, mastering how data flows from raw to actionable insight will save you months of confusion and make your dashboards far more valuable than any fancy visual ever could.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's been your biggest challenge learning Power BI? Drop a comment below,I'd love to hear what trips people up or what clicked for you.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>powerbi</category>
      <category>beginners</category>
      <category>analytics</category>
      <category>learning</category>
    </item>
    <item>
      <title>Power BI Data Modeling</title>
      <dc:creator>Mariam Turnesh</dc:creator>
      <pubDate>Mon, 02 Feb 2026 11:40:29 +0000</pubDate>
      <link>https://forem.com/mariam_turnesh/power-bi-data-modeling-2n39</link>
      <guid>https://forem.com/mariam_turnesh/power-bi-data-modeling-2n39</guid>
      <description>&lt;p&gt;A well-designed Power BI report is built long before the first visual is added. It starts with the data model. When modelling is done poorly, no amount of DAX or formatting can fully fix slow performance or inconsistent numbers.&lt;/p&gt;

&lt;p&gt;In this article, I’ll cover the essentials of data modelling in Power BI fact tables, dimension tables, relationships and star schemas and explain how these design choices directly impact performance and accuracy. If you want reports that scale and behave predictably, this is where it all begins.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Exactly Is Data Modeling in Power BI?
&lt;/h2&gt;

&lt;p&gt;Data modeling is the process of structuring your data tables and establishing connections between them within Power BI's Model view. Think of it as creating the blueprint for how your data will be queried, filtered, and analyzed.&lt;/p&gt;

&lt;p&gt;Here's what many beginners don't realize: Power BI was built for analytical processing, not transactional systems. This means the traditional database designs you might be familiar with often need to be restructured for optimal performance in Power BI. The way you organize and link your tables directly impacts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Query speed&lt;/strong&gt; – How fast your visuals load&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Calculation accuracy&lt;/strong&gt; – Whether your numbers are correct&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User experience&lt;/strong&gt; – How intuitive your reports feel&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt; – How well your model grows with your business&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;A well-designed Power BI data model should:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mirror real-world business logic and processes
&lt;/li&gt;
&lt;li&gt;Minimize complexity in DAX calculations
&lt;/li&gt;
&lt;li&gt;Enable fast query execution
-Guarantee accurate and consistent reporting results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Understanding the Building Blocks: Fact and Dimension Tables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every effective Power BI model is built on two fundamental table types: fact tables and dimension tables. Understanding the distinction between these is crucial for building models that perform well and make logical sense.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Fact Tables: The Measurable Data&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Fact tables are where your business transactions and measurable events live. These tables contain the numeric values you'll aggregate in your reports—the "what happened" of your business.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-world examples of fact tables:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sales transactions (daily orders, revenue, units sold)&lt;/li&gt;
&lt;li&gt;Website analytics (page views, clicks, session duration)&lt;/li&gt;
&lt;li&gt;Manufacturing data (units produced, defect rates, cycle times)&lt;/li&gt;
&lt;li&gt;Financial records (expenses, payments, invoices)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key characteristics of fact tables:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Numeric focus&lt;/strong&gt; – Contain measures that can be summed, averaged, or counted&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Foreign keys&lt;/strong&gt; – Have columns that reference dimension tables&lt;br&gt;&lt;br&gt;
&lt;strong&gt;High row count&lt;/strong&gt; – Often contain millions or billions of records&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Transaction-based&lt;/strong&gt; – Each row represents a business event or observation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example fact table structure:&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.amazonaws.com%2Fuploads%2Farticles%2F8c8dqarsefs8ratgn234.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%2F8c8dqarsefs8ratgn234.png" alt=" " width="242" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dimension Tables: The Descriptive Context&lt;/strong&gt;&lt;br&gt;
Dimension tables provide the context and descriptive attributes that make your fact data meaningful. These tables answer the "who," "what," "where," "when," and "why" questions about your business events.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Real-world examples of dimension tables:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product catalog (names, categories, brands, SKUs)&lt;/li&gt;
&lt;li&gt;Customer directory (names, locations, demographics, segments)&lt;/li&gt;
&lt;li&gt;Date calendar (dates, months, quarters, fiscal years)&lt;/li&gt;
&lt;li&gt;Employee roster (names, departments, job titles, managers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key characteristics of dimension tables:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Descriptive focus&lt;/strong&gt; – Contain text, categories, and attributes
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Primary keys&lt;/strong&gt; – Have unique identifiers that link to fact tables
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Low row count&lt;/strong&gt; – Typically contain hundreds to thousands of records
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference data&lt;/strong&gt; – Used for filtering, grouping, and slicing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example dimension table structure:&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.amazonaws.com%2Fuploads%2Farticles%2Fh961d9woxzx3dccff5is.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%2Fh961d9woxzx3dccff5is.png" alt=" " width="342" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Quick Mental Check:&lt;/strong&gt; If you're summing it up in a report, it belongs in a fact table. If you're filtering or grouping by it, it belongs in a dimension table.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;The Star Schema&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The star schema is the most recommended data modeling approach in Power BI, and for good reason. It's called a "star" schema because when you visualize it in Model view, it literally looks like a star—with your fact table at the center and dimension tables radiating outward.&lt;/p&gt;

&lt;p&gt;What Makes a Star Schema?&lt;/p&gt;

&lt;p&gt;In a star schema design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Central fact table&lt;/strong&gt; – Contains all measurable transaction data
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Surrounding dimensions&lt;/strong&gt; – Connected directly to the fact table
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct relationships&lt;/strong&gt; – Each dimension links straight to facts, no intermediaries
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No dimension-to-dimension links&lt;/strong&gt; – Dimensions remain independent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Characteristics In a star schema&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One central fact table&lt;/li&gt;
&lt;li&gt;Dimension tables connect directly to the fact table&lt;/li&gt;
&lt;li&gt;One-to-many relationships&lt;/li&gt;
&lt;li&gt;No relationships between dimension tables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Star Schema Works Best in Power BI&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Faster performance (fewer joins)&lt;/li&gt;
&lt;li&gt;Simpler DAX calculations&lt;/li&gt;
&lt;li&gt;Easier to understand and maintain&lt;/li&gt;
&lt;li&gt;Optimized for Power BI’s VertiPaq engine&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Visual representation:&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.amazonaws.com%2Fuploads%2Farticles%2Fjhu095rwm82cfgzzjj4q.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%2Fjhu095rwm82cfgzzjj4q.png" alt=" " width="798" height="518"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Snowflake Schema&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The snowflake schema takes the star schema concept and normalizes the dimension tables by breaking them into multiple related sub-tables. While this might seem like good database design (and it is for transactional systems), it's typically problematic in Power BI's analytical environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduces data redundancy&lt;/li&gt;
&lt;li&gt;Can help manage very large or complex dimensions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages in Power BI&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More relationships to manage&lt;/li&gt;
&lt;li&gt;Slower performance due to extra joins&lt;/li&gt;
&lt;li&gt;More complex DAX expressions&lt;/li&gt;
&lt;li&gt;Harder for report users to understand&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of these drawbacks, snowflake schemas are generally discouraged in Power BI, unless there is a specific need.&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%2F2fxxbqieckm6ptjg8705.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%2F2fxxbqieckm6ptjg8705.png" alt=" " width="611" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Relationships in Power BI&lt;/strong&gt;&lt;br&gt;
Power BI supports several relationship types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-to-many (1:*) – most common and recommended&lt;/li&gt;
&lt;li&gt;Many-to-many (&lt;em&gt;:&lt;/em&gt;) – use cautiously&lt;/li&gt;
&lt;li&gt;One-to-one (1:1) – less common&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Relationship Best Practices&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dimension tables should be on the one side&lt;/li&gt;
&lt;li&gt;Fact tables should be on the many side&lt;/li&gt;
&lt;li&gt;Prefer single-direction filtering&lt;/li&gt;
&lt;li&gt;Avoid unnecessary bi-directional relationships&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why Good Data Modelling Is Critical&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;1. Performance&lt;/strong&gt;&lt;br&gt;
Well-designed star schemas reduce joins and allow Power BI to process queries faster. Poor modelling often results in slow-loading visuals and sluggish reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Accurate Reporting&lt;/strong&gt;&lt;br&gt;
Incorrect relationships or poorly structured tables can cause duplicated values, missing data, or misleading totals. Good modelling ensures calculations reflect business reality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Simpler DAX&lt;/strong&gt;&lt;br&gt;
Clean models lead to simpler, more readable DAX measures. This reduces development time and minimizes errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Scalability&lt;/strong&gt;&lt;br&gt;
As datasets grow, a solid data model can handle new dimensions, additional facts, and more complex analysis without requiring major redesigns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Better User Experience&lt;/strong&gt;&lt;br&gt;
End users benefit from intuitive field lists, reliable slicers, and predictable report behavior—all outcomes of good data modelling.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Schemas and data modelling are at the heart of effective Power BI solutions. By organizing data into fact and dimension tables and adopting a star schema approach, analysts can build models that are fast, accurate, and easy to maintain. While snowflake schemas may reduce redundancy, they often introduce unnecessary complexity and performance issues in Power BI.&lt;/p&gt;

&lt;p&gt;Ultimately, good data modelling is not just a technical best practice—it is essential for delivering trustworthy insights and high-quality business intelligence.&lt;/p&gt;

</description>
      <category>powerbi</category>
      <category>beginners</category>
      <category>datamodelling</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Power BI Data Modeling: Why Your Reports Are Slow (And How to Fix Them)</title>
      <dc:creator>Mariam Turnesh</dc:creator>
      <pubDate>Mon, 02 Feb 2026 08:23:24 +0000</pubDate>
      <link>https://forem.com/mariam_turnesh/power-bi-data-modeling-made-simple-your-complete-beginners-guide-17il</link>
      <guid>https://forem.com/mariam_turnesh/power-bi-data-modeling-made-simple-your-complete-beginners-guide-17il</guid>
      <description>&lt;h1&gt;
  
  
  Power BI Data Modeling: Why Your Reports Are Slow (And How to Fix Them)
&lt;/h1&gt;

&lt;p&gt;Look, I'm going to be honest with you. When I first started with Power BI, I thought data modeling was just some boring technical thing that database people worried about. I was wrong. Really wrong.&lt;/p&gt;

&lt;p&gt;My first dashboard took &lt;strong&gt;45 seconds&lt;/strong&gt; to load a single visual. My manager wasn't impressed. Neither were the users who had to stare at loading spinners. The worst part? My numbers didn't even add up correctly half the time.&lt;/p&gt;

&lt;p&gt;Turns out, if you get your data model wrong, nothing else matters. Your fancy visuals, your beautiful color schemes, your clever DAX formulas - all useless if they're sitting on a broken foundation.&lt;/p&gt;

&lt;p&gt;So let's talk about data modeling, but without the academic jargon. Just the stuff you actually need to know.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Even Is a Data Model?
&lt;/h2&gt;

&lt;p&gt;Think of your data model like organizing your closet. You could throw everything in one giant pile - it all fits, technically. But when you need your favorite shirt, good luck finding it in under 10 minutes.&lt;/p&gt;

&lt;p&gt;A data model is just how you organize your tables and connect them together. That's it. But here's the thing - organize them wrong, and Power BI has to work 10x harder to find what it needs. Organize them right, and everything just... flows.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Two Types of Tables You Need to Know
&lt;/h2&gt;

&lt;p&gt;Before we get into schemas (I promise we'll keep this simple), you need to understand that tables generally fall into two camps:&lt;/p&gt;

&lt;h3&gt;
  
  
  Fact Tables: Where the Numbers Live
&lt;/h3&gt;

&lt;p&gt;This is where your actual business data lives - sales amounts, quantities sold, costs, hours worked. Basically, anything you'd put in a SUM() function.&lt;/p&gt;

&lt;p&gt;Here's a simple sales fact table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;OrderID | CustomerID | ProductID | Date       | Quantity | Revenue
------------------------------------------------------------------
1001    | C101       | P501      | 2024-01-15 | 5        | 500
1002    | C102       | P502      | 2024-01-15 | 2        | 200
1003    | C101       | P503      | 2024-01-16 | 3        | 450
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how there's no customer names or product names here? That's on purpose. This table just holds the transaction facts and references to other tables.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dimension Tables: Where the Context Lives
&lt;/h3&gt;

&lt;p&gt;These tables describe your data. Customer names, product categories, dates, store locations - all the stuff that makes your numbers meaningful.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ProductID | ProductName    | Category     | Brand
--------------------------------------------------
P501      | Laptop Pro 15  | Electronics  | TechCo
P502      | Office Chair   | Furniture    | ComfortCo
P503      | Desk Lamp      | Furniture    | BrightCo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the difference? This table tells us WHAT we sold, while the fact table tells us HOW MUCH.&lt;/p&gt;

&lt;p&gt;![Fact vs Dimension visualization]&lt;/p&gt;

&lt;h2&gt;
  
  
  Star Schema: The Setup That Actually Works
&lt;/h2&gt;

&lt;p&gt;Here's where things get interesting. There are different ways to organize your tables, but in Power BI, one approach wins almost every time: the star schema.&lt;/p&gt;

&lt;p&gt;It's called a star schema because when you look at it in model view, it literally looks like a star. You've got:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One fact table in the middle&lt;/strong&gt; (your sales, transactions, whatever)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dimension tables around the edges&lt;/strong&gt; (customers, products, dates, stores)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct connections&lt;/strong&gt; from each dimension to the fact table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. No complicated chains. No tables connecting to other tables that connect to other tables. Just a clean hub-and-spoke pattern.&lt;/p&gt;

&lt;p&gt;![Star Schema visualization]&lt;/p&gt;

&lt;h3&gt;
  
  
  Why This Works So Well
&lt;/h3&gt;

&lt;p&gt;Power BI's engine (called VertiPaq, if you care) is specifically optimized for this pattern. When someone filters by "Electronics" category:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Filter hits the Product dimension&lt;/li&gt;
&lt;li&gt;Flows directly to the Sales fact table&lt;/li&gt;
&lt;li&gt;Done&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Fast. Simple. Predictable.&lt;/p&gt;

&lt;p&gt;Compare that to having your categories in a separate table, connected to subcategories, connected to products, connected to sales. Now Power BI has to hop through three relationships instead of one. Multiply that by thousands of filter selections, and you see why your reports are slow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Snowflake Schema: When You Normalize Too Much
&lt;/h2&gt;

&lt;p&gt;Now, you might see some data models that look more like snowflakes - where dimension tables are split up and connected to each other. Like having:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product table → connects to → SubCategory table → connects to → Category table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called a snowflake schema. It's "normalized" in database terms, which sounds fancy but usually just means "unnecessarily complicated for Power BI."&lt;/p&gt;

&lt;p&gt;![Snowflake Schema visualization]&lt;/p&gt;

&lt;h3&gt;
  
  
  Why You Probably Don't Want This
&lt;/h3&gt;

&lt;p&gt;Yeah, it saves some storage space. And yeah, it follows traditional database design principles. But:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It's slower&lt;/strong&gt; - more relationships to traverse&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's confusing&lt;/strong&gt; - users can't easily find what they need&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It doesn't play well with DAX&lt;/strong&gt; - time intelligence functions hate this pattern&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The only time I use snowflake schema is when I'm importing from a data warehouse that's already set up this way AND I'm too lazy to flatten it in Power Query. (Don't be like me - flatten it.)&lt;/p&gt;

&lt;h2&gt;
  
  
  Relationships: The Glue That Holds Everything Together
&lt;/h2&gt;

&lt;p&gt;Here's something that took me way too long to understand: relationships aren't just lines connecting tables. They control how filters flow through your model.&lt;/p&gt;

&lt;h3&gt;
  
  
  One-to-Many: Your New Best Friend
&lt;/h3&gt;

&lt;p&gt;This is the standard, and you want almost all your relationships to look like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;One&lt;/strong&gt; customer in the customer table&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Many&lt;/strong&gt; orders in the sales table for that customer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The "one" side is your dimension, the "many" side is your fact table. Power BI automatically detects these and sets them up correctly... most of the time.&lt;/p&gt;

&lt;p&gt;![Relationships visualization]&lt;/p&gt;

&lt;h3&gt;
  
  
  The Filter Direction Trap
&lt;/h3&gt;

&lt;p&gt;By default, filters flow from the "one" side to the "many" side. Makes sense - when you select a customer, you want to see their sales, not the other way around.&lt;/p&gt;

&lt;p&gt;But sometimes people get clever and set relationships to filter "both ways." Don't do this unless you absolutely have to. It causes weird stuff to happen, kills performance, and makes debugging a nightmare.&lt;/p&gt;

&lt;p&gt;I spent three hours once trying to figure out why my totals were wrong. Turns out I had a bi-directional relationship I forgot about. Three. Hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This All Actually Matters
&lt;/h2&gt;

&lt;p&gt;Remember how I said my first dashboard took 45 seconds to load? Here's what happened after I rebuilt it with a proper star schema:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load time: 45 seconds&lt;/li&gt;
&lt;li&gt;Refresh time: 30 minutes&lt;/li&gt;
&lt;li&gt;File size: 2.1 GB&lt;/li&gt;
&lt;li&gt;User complaints: Daily&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Load time: Instant&lt;/li&gt;
&lt;li&gt;Refresh time: 3 minutes&lt;/li&gt;
&lt;li&gt;File size: 650 MB&lt;/li&gt;
&lt;li&gt;User complaints: None (they actually started asking for MORE reports)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Same data. Same visuals. Just organized properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Wins You Can Implement Today
&lt;/h2&gt;

&lt;p&gt;Here's the stuff that made the biggest difference for me:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create a proper date table&lt;/strong&gt;&lt;br&gt;
Don't use the auto-generated one. Make your own with Year, Quarter, Month, Week, Day columns. Your time intelligence functions will thank you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Use integer keys for relationships&lt;/strong&gt;&lt;br&gt;
CustomerID should be a number, not text. Same with ProductID, DateKey, everything. Numbers are way faster to match than text.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Remove columns you don't need&lt;/strong&gt;&lt;br&gt;
That 100-column table from your ERP system? You probably use 10 of those columns. Delete the rest in Power Query. Your model will be smaller and faster.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Hide your foreign keys&lt;/strong&gt;&lt;br&gt;
Users don't need to see CustomerID in the field list - they should see Customer Name. Right-click those ID columns and hide them from report view.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Star schema is the default, always&lt;/strong&gt;&lt;br&gt;
Unless you have a really good reason not to, go with star schema. It's what Microsoft recommends, what the engine optimizes for, and what actually works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The One Thing You Need to Remember
&lt;/h2&gt;

&lt;p&gt;If you take nothing else from this article, remember this: &lt;strong&gt;your data model is more important than your visuals&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You can have the most beautiful dashboard in the world, but if it's built on a messy, slow data model, nobody's going to use it. They'll just go back to Excel.&lt;/p&gt;

&lt;p&gt;But nail the data model? Everything else becomes easy. Visuals load fast. Filters work correctly. DAX formulas make sense. Users are happy.&lt;/p&gt;

&lt;p&gt;And honestly, that's all that matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;Start with your worst-performing report. Open up the model view. Look at your relationships. I'm willing to bet you'll find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tables that shouldn't be connected&lt;/li&gt;
&lt;li&gt;Bi-directional relationships you don't need&lt;/li&gt;
&lt;li&gt;Snowflake patterns you can flatten&lt;/li&gt;
&lt;li&gt;Missing relationships that should exist&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fix those, and watch your performance problems disappear.&lt;/p&gt;

&lt;p&gt;Have questions about data modeling? Drop them in the comments. I've probably made every mistake in the book, so I can probably help you avoid them.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Quick Reference:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Use star schema&lt;/strong&gt; (fact table in center, dimensions around it)&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;One-to-many relationships&lt;/strong&gt; (dimension → fact)&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Single direction filtering&lt;/strong&gt; (no bi-directional unless necessary)&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Create a date dimension&lt;/strong&gt; (don't use auto-date)&lt;br&gt;&lt;br&gt;
✅ &lt;strong&gt;Hide foreign key columns&lt;/strong&gt; (show names, not IDs)  &lt;/p&gt;

&lt;p&gt;❌ &lt;strong&gt;Avoid snowflake schema&lt;/strong&gt; (flatten in Power Query instead)&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Avoid many-to-many&lt;/strong&gt; (create bridge tables if needed)&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Don't import unnecessary columns&lt;/strong&gt; (remove in Power Query)&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Don't use text for keys&lt;/strong&gt; (use integers)&lt;br&gt;&lt;br&gt;
❌ &lt;strong&gt;Don't skip data modeling&lt;/strong&gt; (it's not optional)  &lt;/p&gt;




&lt;p&gt;&lt;em&gt;Found this helpful? Share it with someone struggling with slow Power BI reports. We've all been there.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>powerbi</category>
      <category>datamodeling</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Introduction to MS Excel for Data Analytics</title>
      <dc:creator>Mariam Turnesh</dc:creator>
      <pubDate>Sun, 25 Jan 2026 20:33:09 +0000</pubDate>
      <link>https://forem.com/mariam_turnesh/ms-excel-for-data-analytics-a-beginners-guide-2fa3</link>
      <guid>https://forem.com/mariam_turnesh/ms-excel-for-data-analytics-a-beginners-guide-2fa3</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you're stepping into data analytics, &lt;strong&gt;Excel is your best friend&lt;/strong&gt;. It's the most accessible, powerful tool for working with data - no coding required. Whether you're tracking sales, analyzing trends, or building reports, Excel has you covered.&lt;/p&gt;

&lt;p&gt;This guide uses real examples to make learning fun and relatable. By the end, you'll know how to clean data, write formulas, create pivot tables and extract insights like a pro.&lt;/p&gt;

&lt;p&gt;Let's dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  Part 1: Understanding the Excel Interface
&lt;/h2&gt;

&lt;p&gt;Before we jump into formulas and functions, let's get comfortable with Excel's layout.&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%2Fxf9vat6u34vxpsxi1tjn.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%2Fxf9vat6u34vxpsxi1tjn.png" alt=" " width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key components you need to know:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ribbon&lt;/strong&gt;: The toolbar at the top with tabs (Home, Insert, Formulas, Data, etc.) - this is where all Excel's features live&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Formula Bar&lt;/strong&gt;: Shows the contents of the active cell - especially useful when viewing formulas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Column Headers&lt;/strong&gt;: The letters (A, B, C...) that identify columns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Row Headers&lt;/strong&gt;: The numbers (1, 2, 3...) that identify rows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active Cell&lt;/strong&gt;: The currently selected cell with a green border (like A1 in the image)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Worksheet Tabs&lt;/strong&gt;: Switch between different sheets in your workbook (Sheet1, Sheet2, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pro tip&lt;/strong&gt;: When someone says "cell D5", they mean the intersection of column D and row 5. This naming system is how we reference data in formulas.&lt;/p&gt;




&lt;h2&gt;
  
  
  PART 2: Data Cleaning &amp;amp; Sorting/Filtering
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;1. How to Find Duplicates&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You might want to see duplicates before deleting them to be sure what you’re removing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Highlight Duplicates Using Conditional Formatting&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select the cells you want to check.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click Home → Conditional Formatting → Highlight Cells Rules → Duplicate Values.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pick a color style and click OK.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now all duplicates will be colored so you can see them easily.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ This doesn’t delete anything, it just shows duplicates so you can inspect them.&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%2Ft8d9fusv3ldtuzkruzbi.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%2Ft8d9fusv3ldtuzkruzbi.png" alt=" " width="365" height="413"&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%2F2jhayfwu2zdxk0lclqhp.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%2F2jhayfwu2zdxk0lclqhp.png" alt=" " width="467" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. How to Remove Duplicates&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re sure you want to delete the extra copies:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use the Remove Duplicates Tool&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select your data range (just click anywhere inside your table).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to Data → Remove Duplicates.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A box will pop up. Excel will usually guess your column headers for you.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure the columns you want to check for duplicates are ticked.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click OK.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Excel will remove all rows that are exact duplicates and leave only the first occurrence. It will also tell you how many duplicates it found and removed.&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%2F34xg6ufcregu8gvr0clz.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%2F34xg6ufcregu8gvr0clz.png" alt=" " width="593" height="416"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3.Find &amp;amp; Replace&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Find and Replace is a feature in Excel that helps you quickly search for specific text or numbers and change them across your worksheet. It’s especially useful when cleaning data or fixing repeated mistakes.&lt;/p&gt;

&lt;p&gt;Use Ctrl + F to find data and Ctrl + H to replace it. This feature saves time, fixes repeated errors, and helps clean data, but you should be careful with Replace All since it changes everything at once. &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%2Ft6owp6u7lg818ap1zc41.jpg" 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%2Ft6owp6u7lg818ap1zc41.jpg" alt=" " width="600" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Sorting and Filtering&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Sorting and Filtering help you organize data and focus only on what matters, without changing the actual data.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Sorting&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Sorting in Excel helps you arrange your data in a meaningful order so it’s easier to understand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Types of Sorting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Text&lt;/strong&gt;: A → Z or Z → A&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Numbers&lt;/strong&gt;: Smallest → Largest or Largest → Smallest&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dates&lt;/strong&gt;: Oldest → Newest or Newest → Oldest&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Sort Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click anywhere inside your table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to Data → Sort A–Z or Sort Z–A.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Excel will reorder the rows based on the selected column.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2F5jlic2zbkior9z6a8dee.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%2F5jlic2zbkior9z6a8dee.png" alt=" " width="716" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Filtering&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Filtering in Excel lets you show only the data you want to see while hiding the rest. It helps you focus on specific information without deleting anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Apply a Filter&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click anywhere inside your table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to Data → Filter.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click the dropdown arrow in a column header.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Choose the values you want to see and click OK.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&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%2Foyaws1s3625ktza3fgv7.jpg" 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%2Foyaws1s3625ktza3fgv7.jpg" alt=" " width="559" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Freeze Panes in Excel&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Freeze Panes is an Excel feature that keeps certain rows or columns visible while you scroll through your worksheet. This is helpful when working with large tables, so you don’t lose sight of headers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to Use Freeze Panes&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Click the cell below the row or to the right of the column you want to keep visible.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to View → Freeze Panes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Choose:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Freeze Top Row&lt;/strong&gt; – keeps column headers visible&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Freeze First Column&lt;/strong&gt; – keeps row labels visible&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Freeze Panes&lt;/strong&gt; – freezes both rows and columns&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%2Fvbbc63a5gkd32ntzyszy.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%2Fvbbc63a5gkd32ntzyszy.png" alt=" " width="618" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Part 3: Basic Functions in Excel&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In Excel, functions are built-in formulas that help you perform calculations quickly and correctly. Instead of doing math by hand, you tell Excel what to calculate.&lt;/p&gt;

&lt;p&gt;All functions start with an equals sign &lt;strong&gt;(=)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Functions are pre-built formulas that perform calculations for you. Let's look at the most important ones you'll use every day.&lt;/p&gt;

&lt;h3&gt;
  
  
  The SUM Function
&lt;/h3&gt;

&lt;p&gt;Need to add up numbers quickly? SUM is your go-to 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%2Flz0cmnrr49k4qtggyi1r.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%2Flz0cmnrr49k4qtggyi1r.png" alt=" " width="800" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=SUM(D2:D10)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This adds all values from cell D2 through D10&lt;/li&gt;
&lt;li&gt;Result: 2489 &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Real-world use&lt;/strong&gt;: Totaling sales, expenses, inventory quantities, hours worked, etc.&lt;/p&gt;




&lt;h3&gt;
  
  
  The AVERAGE Function
&lt;/h3&gt;

&lt;p&gt;Want to find the mean of a group of numbers? AVERAGE does the math for you.&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%2Fv0wqvsls424a90aa2pmh.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%2Fv0wqvsls424a90aa2pmh.png" alt=" " width="800" height="248"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=AVERAGE(B2:E2)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This calculates the average of values across columns B through E in row 2&lt;/li&gt;
&lt;li&gt;Result: 4 (average number of pokeballs for trainer Iva)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why it matters&lt;/strong&gt;: Averages help you understand typical values in your data - average sales per month, average customer rating, average response time, etc.&lt;/p&gt;




&lt;h3&gt;
  
  
  The MAX and MIN Functions
&lt;/h3&gt;

&lt;p&gt;These functions find the highest and lowest values in a range.&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%2Fzal3ukbpzos9pbyfq579.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%2Fzal3ukbpzos9pbyfq579.png" alt=" " width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's happening:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=MAX(D2:D21)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Finds the highest value in the Total stats column&lt;/li&gt;
&lt;li&gt;Result: 525 (Cloyster has the highest stats)&lt;/li&gt;
&lt;/ul&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%2F1jop0yqfa9r7stiuea8p.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%2F1jop0yqfa9r7stiuea8p.png" alt=" " width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's happening:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=MIN(D2:D21)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Finds the lowest value in the Total stats column&lt;/li&gt;
&lt;li&gt;Result: 200 (Magikarp has the lowest stats)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Real-world applications:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MAX&lt;/strong&gt;: Find your best-selling product, highest revenue month, top performer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MIN&lt;/strong&gt;: Identify lowest inventory levels, minimum order quantities, slowest sales day&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  The MEDIAN Function
&lt;/h3&gt;

&lt;p&gt;While AVERAGE can be skewed by extreme values, MEDIAN finds the true middle value.&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%2Fbv3j5nyl9ia6k8dlepoc.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%2Fbv3j5nyl9ia6k8dlepoc.png" alt=" " width="512" height="128"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's happening:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=MEDIAN(A2:G2)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Finds the middle value when all numbers are sorted&lt;/li&gt;
&lt;li&gt;Result: 2&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When to use MEDIAN vs AVERAGE&lt;/strong&gt;: If you have outliers (extremely high or low values), MEDIAN gives you a better sense of the "typical" value. For example, median income is often more useful than average income because a few billionaires don't skew it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Logical Functions
&lt;/h2&gt;

&lt;p&gt;Logical functions help Excel make decisions based on conditions you set. They're like teaching Excel to think: "If this is true, do that. Otherwise, do something else."&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The IF Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The IF function is your decision-maker. It checks a condition and returns one value if true, another if false.&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%2Flnfmj5qg2u6y5safb2lw.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%2Flnfmj5qg2u6y5safb2lw.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=IF(C5&amp;gt;80,TRUE)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Logic: If the Score (in column C) is greater than 80, display TRUE, otherwise display FALSE&lt;/li&gt;
&lt;li&gt;Result: 

&lt;ul&gt;
&lt;li&gt;Ava Thompson (85) → TRUE&lt;/li&gt;
&lt;li&gt;Lily Smith (79) → FALSE&lt;/li&gt;
&lt;li&gt;Ethan Johnson (82) → TRUE&lt;/li&gt;
&lt;li&gt;And so on...&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; This simple IF formula evaluates each student's score and returns TRUE for passing scores (&amp;gt;80) and FALSE for those who didn't meet the threshold.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The AND Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;AND checks if ALL conditions are true. Every single condition must pass.&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%2F1jcqh90n61mol2zz8qms.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%2F1jcqh90n61mol2zz8qms.png" alt=" " width="384" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=AND(B2&amp;gt;=60, C2&amp;gt;=90)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Logic: Returns TRUE only if BOTH Score 1 is greater than or equal to 60 AND Score 2 is greater than or equal to 90&lt;/li&gt;
&lt;li&gt;Result: 

&lt;ul&gt;
&lt;li&gt;Richard (53, 80) → FALSE (Score 1 fails)&lt;/li&gt;
&lt;li&gt;Jennifer (60, 91) → TRUE (both conditions met)&lt;/li&gt;
&lt;li&gt;James (58, 75) → FALSE (both conditions fail)&lt;/li&gt;
&lt;li&gt;Lisa (79, 51) → FALSE (Score 2 fails)&lt;/li&gt;
&lt;li&gt;Sharon (41, 33) → FALSE (both conditions fail)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; ALL conditions must be satisfied. If even one condition is false, the entire AND function returns FALSE.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The OR Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;OR checks if AT LEAST ONE condition is true. Only one needs to pass.&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%2F7cm6jnrbl3eq5cposr3q.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%2F7cm6jnrbl3eq5cposr3q.png" alt=" " width="720" height="425"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=OR(B8&amp;gt;30, C8="North")&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Logic: Returns TRUE if EITHER Sales Volume is greater than 30 OR Team equals "North"&lt;/li&gt;
&lt;li&gt;Result: 

&lt;ul&gt;
&lt;li&gt;Malkowitz, Sally (18, North) → TRUE (Team is North)&lt;/li&gt;
&lt;li&gt;Wilson, Timothy (31, East) → TRUE (Sales &amp;gt; 30)&lt;/li&gt;
&lt;li&gt;Birch, Julia (42, West) → TRUE (Sales &amp;gt; 30)&lt;/li&gt;
&lt;li&gt;Fairclough, John (57, North) → TRUE (both conditions met!)&lt;/li&gt;
&lt;li&gt;Johnson, Mark (30, East) → FALSE (Sales not &amp;gt; 30 AND Team not North)&lt;/li&gt;
&lt;li&gt;Williams, Eric (16, South) → FALSE (neither condition met)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; Only ONE condition needs to be true. If any condition passes, the entire OR function returns TRUE.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The NOT Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;NOT reverses the logic. It turns TRUE into FALSE and FALSE into TRUE.&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%2Fm3evxczgj0ajgm3p0ogo.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%2Fm3evxczgj0ajgm3p0ogo.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=NOT(OR(B5="green", B5="red"))&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Logic: First checks if Color is green OR red, then reverses that result&lt;/li&gt;
&lt;li&gt;Result: 

&lt;ul&gt;
&lt;li&gt;Red → FALSE (NOT green or red = NOT TRUE = FALSE)&lt;/li&gt;
&lt;li&gt;Blue → TRUE (NOT green or red = NOT FALSE = TRUE)&lt;/li&gt;
&lt;li&gt;Green → FALSE (NOT green or red = NOT TRUE = FALSE)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; NOT flips the logic. It's useful when you want to find everything EXCEPT certain values.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Text Functions&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Text functions help you manipulate, clean, and standardize text data. Essential for messy real-world datasets!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The TRIM Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;TRIM removes extra spaces that mess up your data.&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%2Fkgiopwgazyx131z9youl.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%2Fkgiopwgazyx131z9youl.png" alt=" " width="252" height="200"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Formula: &lt;code&gt;=TRIM(A2)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Original data has inconsistent spacing (extra spaces before, after, or between names)&lt;/li&gt;
&lt;li&gt;Result: Clean, properly formatted names

&lt;ul&gt;
&lt;li&gt;" Ronnie Anderson" → "Ronnie Anderson"&lt;/li&gt;
&lt;li&gt;"Tom    Boone" → "Tom Boone"&lt;/li&gt;
&lt;li&gt;"Sally Brooke   " → "Sally Brooke"&lt;/li&gt;
&lt;li&gt;"Jeremy    Hill" → "Jeremy Hill"&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt; Excel treats " Ronnie Anderson" and "Ronnie Anderson" as different values. When counting or filtering, extra spaces create duplicate entries and wrong totals. TRIM fixes this instantly.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The UPPER, LOWER, and PROPER Functions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The Excel functions UPPER, LOWER and PROPER change text case: &lt;strong&gt;UPPER&lt;/strong&gt; converts all letters to caps&lt;br&gt;&lt;br&gt;
&lt;strong&gt;LOWER&lt;/strong&gt; converts all to lowercase&lt;br&gt;
&lt;strong&gt;PROPER&lt;/strong&gt; capitalizes only the first letter of each word (useful for names)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Upper Function&lt;/strong&gt;
&lt;/h2&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%2Fkerw1pav7r27fzp8esvl.webp" 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%2Fkerw1pav7r27fzp8esvl.webp" alt=" " width="530" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What's happening here:&lt;/p&gt;

&lt;p&gt;Formula: =UPPER(A4)&lt;br&gt;
Converts all text to UPPERCASE&lt;br&gt;
Examples from the data:&lt;/p&gt;

&lt;p&gt;"william" → "WILLIAM"&lt;br&gt;
"jody" → "JODY"&lt;br&gt;
"sophie" → "SOPHIE"&lt;br&gt;
"gurpreet" → "GURPREET"&lt;br&gt;
"maximus" → "MAXIMUS"&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;lower Function&lt;/strong&gt;
&lt;/h2&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%2Fdhfqcoqd3netwatcvkxh.webp" 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%2Fdhfqcoqd3netwatcvkxh.webp" alt=" " width="564" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Formula: =LOWER(A4)&lt;br&gt;
Converts all text to lowercase&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;"william" → "william"&lt;br&gt;
"JODY" → "jody"&lt;br&gt;
"SOPHIE" → "sophie"&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Proper Function&lt;/strong&gt;
&lt;/h2&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%2Ffnwh3bl45dzzq9762kfi.webp" 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%2Ffnwh3bl45dzzq9762kfi.webp" alt=" " width="551" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Formula: =PROPER(A4)&lt;br&gt;
Capitalizes the first letter of each word (Title Case)&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;"william" → "William"&lt;br&gt;
"jody" → "Jody"&lt;br&gt;
"sophie" → "Sophie"&lt;br&gt;
"gurpreet" → "Gurpreet"&lt;br&gt;
"maximus" → "Maximus"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Insight&lt;/strong&gt;: These three functions give you complete control over text capitalization. UPPER for acronyms and codes, LOWER for email addresses and PROPER for names and titles.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The CONCATENATE Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Combine text from multiple cells into one.&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%2F7od9nft3yk9w7lf0ubs1.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%2F7od9nft3yk9w7lf0ubs1.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What's happening here&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Formula: =CONCATENATE(B5,", ",C5,", ",D5) or using &amp;amp;: =B5&amp;amp;", "&amp;amp;C5&amp;amp;", "&amp;amp;D5&lt;br&gt;
Combines multiple values with separators&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;Values A, B, C → "A, B, C"&lt;br&gt;
Numbers 1, 2, 3 → "1, 2, 3"&lt;br&gt;
"apples", "oranges", "pears" → "apples, oranges, pears"&lt;br&gt;
"red", "blue", "green" → "red, blue, green"&lt;br&gt;
Title "Mr.", First "Bob", Last "Smith" → "Mr. Bob Smith"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro tip&lt;/strong&gt;: The &amp;amp; symbol is faster to type and does the same thing!&lt;br&gt;
Real-world use: Create full names from first/last names, combine address fields (street + city + state), build product descriptions, generate email addresses (&lt;a href="mailto:first.last@company.com"&gt;first.last@company.com&lt;/a&gt;)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;LEFT Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The LEFT function is used to retrieve a chosen amount of characters, counting from the left side of an Excel cell.&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%2Fbmwxhxr715sovhnbxxih.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%2Fbmwxhxr715sovhnbxxih.png" alt=" " width="434" height="400"&gt;&lt;/a&gt;&lt;br&gt;
What's happening here:&lt;/p&gt;

&lt;p&gt;Formula: =LEFT(B5, 3)&lt;br&gt;
Extracts the first 3 characters from the left&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;"January" → "Jan"&lt;br&gt;
"February" → "Feb"&lt;br&gt;
"March" → "Mar"&lt;br&gt;
"April" → "Apr"&lt;br&gt;
"September" → "Sep"&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;RIGHT Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The RIGHT function is used to retrieve a chosen amount of characters, counting from the right side of an Excel cell. &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%2Fhfosfa7mbzx0wequ1763.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%2Fhfosfa7mbzx0wequ1763.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Formula: =RIGHT(B5, 1) or =RIGHT(B5, 2) or =RIGHT(B5, 3)&lt;br&gt;
Extracts characters from the right side&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;"ABC" with RIGHT(B5,1) → "C"&lt;br&gt;
"ABC" with RIGHT(B5,2) → "BC"&lt;br&gt;
"Portland, OR" with RIGHT(B8,2) → "OR"&lt;br&gt;
"google.com" with RIGHT(B10,3) → "com"&lt;br&gt;
"+1 303-512-4271" with RIGHT(B12,12) → "303-512-4271"&lt;br&gt;
"2000 x 3000" with RIGHT(B14,4) → "3000"&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Date &amp;amp; Time Functions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Excel stores dates as numbers (January 1, 1900 = 1), which means you can do math with dates! These functions make working with dates much easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The TODAY Functions&lt;/strong&gt;&lt;br&gt;
Get the current date or date and time.&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%2Fzuxy8x6nz8o2b470ctoh.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%2Fzuxy8x6nz8o2b470ctoh.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Formula: =TODAY()&lt;br&gt;
Returns current date only (no time component)&lt;br&gt;
Note: These functions take NO arguments - just empty parentheses!&lt;br&gt;
Examples of using TODAY():&lt;/p&gt;

&lt;p&gt;=TODAY() → 31-May-21 (current date)&lt;br&gt;
=TODAY()-7 → 24-May-21 (one week in past)&lt;br&gt;
=TODAY()+7 → 7-Jun-21 (one week in future)&lt;br&gt;
=TODAY()+90 → 29-Aug-21 (90 days from today)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The NOW function&lt;/strong&gt;
&lt;/h2&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%2Fs0cra3d0zqekr56menoo.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%2Fs0cra3d0zqekr56menoo.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Formula: =NOW()&lt;br&gt;
Returns current date AND time&lt;br&gt;
Examples of using NOW():&lt;/p&gt;

&lt;p&gt;=NOW() → 31-May-21 17:39 (current date and time)&lt;br&gt;
=NOW()-7 → 24-May-21 17:39 (last week same time)&lt;br&gt;
=NOW()+7 → 7-Jun-21 17:39 (next week same time)&lt;/p&gt;

&lt;p&gt;Important: These functions update automatically every time you open the file or recalculate.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The Year Function&lt;/strong&gt;
&lt;/h2&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%2Flesp1hknocikvlnt31go.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%2Flesp1hknocikvlnt31go.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;br&gt;
What's happening here:&lt;/p&gt;

&lt;p&gt;Formula: =YEAR(B5)&lt;br&gt;
Extracts the year from any date&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;15-Apr-12 → 1912&lt;br&gt;
28-Jun-14 → 1914&lt;br&gt;
29-Oct-29 → 1929&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Month Function&lt;/strong&gt;
&lt;/h2&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%2Fz4jav0jnflqjav0fcs61.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%2Fz4jav0jnflqjav0fcs61.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Formula: =MONTH(B5)&lt;br&gt;
Extracts the month as a number (1-12)&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;15-Apr-1912 → 4 (April)&lt;br&gt;
21-May-1927 → 5 (May)&lt;br&gt;
29-Oct-1929 → 10 (October)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;DAY Function&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Create a date from separate year, month and day 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%2Fu9rtej13z50xyqyxi6nl.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%2Fu9rtej13z50xyqyxi6nl.png" alt=" " width="700" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;What's happening here:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Formula: =DATE(B5, C5, D5)&lt;br&gt;
Combines separate Year, Month, and Day columns into a complete date&lt;br&gt;
Examples:&lt;/p&gt;

&lt;p&gt;Year: 1995, Month: 1, Day: 1 → 1-Jan-1995&lt;br&gt;
Year: 2010, Month: 1, Day: 1 → 1-Jan-2010&lt;br&gt;
Year: 2021, Month: 1, Day: 1 → 1-Jan-2021&lt;br&gt;
Year: 2021, Month: 2, Day: 1 → 1-Feb-2021&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Insight:&lt;/strong&gt; This is incredibly useful when your data has dates split across multiple columns (common in imported data or forms).&lt;/p&gt;




&lt;h2&gt;
  
  
  *&lt;em&gt;Part 4: Pivot Tables *&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Pivot tables are Excel's most powerful feature for analyzing large datasets. They let you summarize, analyze, and explore thousands of rows of data in seconds without writing a single formula.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Think of it this way:&lt;/strong&gt; If you have a list of 1,000 sales transactions, a pivot table can instantly tell you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Total sales by salesperson&lt;/li&gt;
&lt;li&gt;Average order value by month&lt;/li&gt;
&lt;li&gt;Sales by product category and region&lt;/li&gt;
&lt;li&gt;Year-over-year comparisons&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All without a single formula!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Creating Your First Pivot Table&lt;/strong&gt;
&lt;/h2&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%2Frj63857qrn7xydkxax1d.webp" 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%2Frj63857qrn7xydkxax1d.webp" alt=" " width="800" height="519"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Prepare Your Data
&lt;/h3&gt;

&lt;p&gt;Your source data should be organized in a table format with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Headers in the first row&lt;/strong&gt;: Employee Name, Department, Salary, Joining Year, Performance Rating&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No blank rows or columns&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent data types&lt;/strong&gt; in each column&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;One record per row&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2: Insert the Pivot Table&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click anywhere in your data&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Insert tab&lt;/strong&gt; → &lt;strong&gt;PivotTable&lt;/strong&gt; (top-left corner)&lt;/li&gt;
&lt;li&gt;Excel will automatically detect your data range&lt;/li&gt;
&lt;li&gt;In the Create PivotTable dialog:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Table/Range&lt;/strong&gt;: Verify the range (e.g., &lt;code&gt;Sheet3!$A$1:$E$10&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose where to place&lt;/strong&gt;: Select "New Worksheet" (recommended for beginners)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;OK&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Step 3: Build Your Report
&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%2F8vvahsw8cxfd1qxvmjri.webp" 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%2F8vvahsw8cxfd1qxvmjri.webp" alt=" " width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll see a blank pivot table and the &lt;strong&gt;PivotTable Fields&lt;/strong&gt; pane on the right with four areas:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;The Four Key Areas:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;FILTERS&lt;/strong&gt; (top-left box)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add fields here to filter the entire report&lt;/li&gt;
&lt;li&gt;Example: Add "Joining Year" to filter data by year&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;COLUMNS&lt;/strong&gt; (top-right box)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fields placed here become column headers&lt;/li&gt;
&lt;li&gt;Example: Add "Department" to see departments across columns&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;ROWS&lt;/strong&gt; (bottom-left box)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Fields placed here become row labels&lt;/li&gt;
&lt;li&gt;Example: Add "Employee Name" to list employees down the side&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;VALUES&lt;/strong&gt; (bottom-right box)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The actual numbers you want to calculate&lt;/li&gt;
&lt;li&gt;Example: Add "Salary" to calculate sum or average&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Step 4: Drag Fields to Build Your Analysis
&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%2Fnjw2nhky5yo0m0qjqkri.webp" 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%2Fnjw2nhky5yo0m0qjqkri.webp" alt=" " width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Example: Summarize Salaries by Department
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Drag &lt;strong&gt;Department&lt;/strong&gt; → ROWS area&lt;/li&gt;
&lt;li&gt;Drag &lt;strong&gt;Employee Name&lt;/strong&gt; → ROWS area (below Department for grouping)&lt;/li&gt;
&lt;li&gt;Drag &lt;strong&gt;Salary&lt;/strong&gt; → VALUES area&lt;/li&gt;
&lt;li&gt;Drag &lt;strong&gt;Joining Year&lt;/strong&gt; → VALUES area&lt;/li&gt;
&lt;li&gt;Drag &lt;strong&gt;Performance Rating&lt;/strong&gt; → VALUES area&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Key Insights from this Pivot Table:&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;IT department has the highest total salary ($226,600)&lt;/li&gt;
&lt;li&gt;Finance has the highest individual salary (Chris Taylor at $89,300)&lt;/li&gt;
&lt;li&gt;You can see totals by department AND individual employees&lt;/li&gt;
&lt;li&gt;Grand total shows company-wide statistics&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Pivot Charts&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Pivot charts are dynamic charts connected to your pivot table. When you update the pivot table, the chart updates automatically.&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%2F9tvpqsteycwvtp09tgl7.webp" 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%2F9tvpqsteycwvtp09tgl7.webp" alt=" " width="610" height="484"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a Pivot Chart
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Method 1: From Existing Pivot Table&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click anywhere in your pivot table&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Insert tab&lt;/strong&gt; → &lt;strong&gt;PivotChart&lt;/strong&gt; (in the Charts group)&lt;/li&gt;
&lt;li&gt;Choose your chart type&lt;/li&gt;
&lt;/ol&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%2Fmtfalzryf2355vqzzblp.webp" 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%2Fmtfalzryf2355vqzzblp.webp" alt=" " width="634" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Method 2: Create Both at Once&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Select your source data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insert tab&lt;/strong&gt; → &lt;strong&gt;PivotChart&lt;/strong&gt; dropdown → &lt;strong&gt;PivotChart &amp;amp; PivotTable&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Excel creates both simultaneously&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Choosing the Right Chart Type
&lt;/h2&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%2Foi5ehsg9bei44unjuufw.webp" 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%2Foi5ehsg9bei44unjuufw.webp" alt=" " width="730" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Slicers&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Slicers are visual filter buttons that make filtering pivot tables intuitive and user-friendly. Instead of dropdown menus, you get clickable buttons.&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%2Ff64ihuyw04pfps4g2c03.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%2Ff64ihuyw04pfps4g2c03.png" alt=" " width="439" height="463"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What are Slicers?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;In the example above:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Left slicer: Filter by &lt;strong&gt;Product&lt;/strong&gt; (Apples, Bananas, Cherries, Oranges)&lt;/li&gt;
&lt;li&gt;Right slicer: Filter by &lt;strong&gt;Reseller&lt;/strong&gt; (John, Mike, Pete, Sally)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pivot table shows sales data that updates instantly when you click slicer buttons.&lt;/p&gt;




&lt;h2&gt;
  
  
  ** Adding Slicers to Your Pivot Table**
&lt;/h2&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%2Fyvi6cyckk9gky98o769j.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%2Fyvi6cyckk9gky98o769j.png" alt=" " width="408" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Click anywhere in your pivot table&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PivotTable Tools&lt;/strong&gt; → &lt;strong&gt;Analyze tab&lt;/strong&gt; → &lt;strong&gt;Insert Slicer&lt;/strong&gt; (in the Filter group)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In the &lt;strong&gt;Insert Slicers&lt;/strong&gt; dialog, check the fields you want as slicers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;☑ Product&lt;/li&gt;
&lt;li&gt;☑ Reseller&lt;/li&gt;
&lt;li&gt;☐ Month&lt;/li&gt;
&lt;li&gt;☐ Sales&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;OK&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Slicers appear as floating windows you can move and resize.&lt;/p&gt;




&lt;h1&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Excel is more than a spreadsheet,it’s a powerful tool for turning raw data into clear insights. With logical, text and date functions, you can clean data, automate decisions and analyze trends efficiently. Pivot tables, charts, and slicers take this further by helping you summarize, visualize, and explore data with ease.&lt;/p&gt;

&lt;p&gt;You don’t need to know every Excel feature to be effective. What matters is understanding which tool to use and when. With these fundamentals, you’re already equipped to solve most real-world data problems confidently.&lt;/p&gt;

&lt;p&gt;Keep practicing, experiment with your own datasets, and build from here. This foundation sets you up to work smarter, faster, and more confidently with data. 🚀&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>excel</category>
      <category>beginners</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Git &amp; GitHub: Your Quick Start Guide</title>
      <dc:creator>Mariam Turnesh</dc:creator>
      <pubDate>Fri, 16 Jan 2026 17:05:09 +0000</pubDate>
      <link>https://forem.com/mariam_turnesh/understanding-git-and-git-hub-npg</link>
      <guid>https://forem.com/mariam_turnesh/understanding-git-and-git-hub-npg</guid>
      <description>&lt;h2&gt;
  
  
  What's Git Anyway?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Git&lt;/strong&gt; = Time machine for your code. Every change gets saved. You can always go back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt; = Cloud storage for your Git projects. Like Google Drive, but designed for code.&lt;/p&gt;

&lt;p&gt;That's really all you need to know to get started.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Install Git Bash
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://git-scm.com" rel="noopener noreferrer"&gt;git-scm.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Download and run the installer&lt;/li&gt;
&lt;li&gt;Keep the default settings and click "Next" through everything&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Mac
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Linux
&lt;/h3&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;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;git  &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;dnf &lt;span class="nb"&gt;install &lt;/span&gt;git      &lt;span class="c"&gt;# Fedora&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify It Worked
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;p&gt;See a version number? You're good! ✅&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Connect to GitHub
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create Your Account
&lt;/h3&gt;

&lt;p&gt;Head to &lt;a href="https://github.com" rel="noopener noreferrer"&gt;github.com&lt;/a&gt; and sign up. Verify your email.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tell Git Who You Are
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"your@email.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Use the same email as your GitHub account!&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Up SSH Keys (The Better Way)
&lt;/h3&gt;

&lt;p&gt;Instead of typing passwords constantly, use SSH:&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="c"&gt;# Generate your key&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"your@email.com"&lt;/span&gt;

&lt;span class="c"&gt;# Press Enter 3 times (default location, no password)&lt;/span&gt;

&lt;span class="c"&gt;# Display your key&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; ~/.ssh/id_ed25519.pub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy everything that appears (starts with &lt;code&gt;ssh-ed25519&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Now on GitHub:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Settings → SSH and GPG keys&lt;/li&gt;
&lt;li&gt;Click "New SSH key"&lt;/li&gt;
&lt;li&gt;Paste your key and save&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Test the Connection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh &lt;span class="nt"&gt;-T&lt;/span&gt; git@github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See "Hi username!"? Perfect! You're connected. 🎉&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Why Version Control Matters
&lt;/h2&gt;

&lt;p&gt;Without Git, you end up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;project.zip
project_final.zip
project_final_ACTUALLY_FINAL.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Git:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One project folder&lt;/li&gt;
&lt;li&gt;Complete history of all changes&lt;/li&gt;
&lt;li&gt;Ability to jump back to any previous version&lt;/li&gt;
&lt;li&gt;Safe experimentation without fear&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;That's version control.&lt;/strong&gt; It keeps your project history organized and accessible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Track Your First Project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Start a New Project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-project
&lt;span class="nb"&gt;cd &lt;/span&gt;my-project
git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git is now watching this folder!&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a File
&lt;/h3&gt;

&lt;p&gt;Make a file called &lt;code&gt;app.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, Git!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  See What Changed
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Git says: "I see app.py but I'm not tracking it yet."&lt;/p&gt;

&lt;h3&gt;
  
  
  Track the Changes
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;p&gt;This "stages" your changes - telling Git you want to save them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Save a Snapshot (Commit)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Create initial app"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;You just made your first commit!&lt;/strong&gt; It's a saved point you can always return to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good commit messages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"Add login form"&lt;/li&gt;
&lt;li&gt;"Fix mobile navigation bug"&lt;/li&gt;
&lt;li&gt;"Update installation instructions"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Bad commit messages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"stuff"&lt;/li&gt;
&lt;li&gt;"changes"&lt;/li&gt;
&lt;li&gt;"idk"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  View Your History
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's your commit with its unique ID!&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Push to GitHub
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a Repo on GitHub
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click the &lt;strong&gt;+&lt;/strong&gt; icon → New repository&lt;/li&gt;
&lt;li&gt;Name it &lt;code&gt;my-project&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Keep it Public (or choose Private)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Don't&lt;/strong&gt; initialize with README&lt;/li&gt;
&lt;li&gt;Click "Create repository"&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Link and Upload
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git remote add origin git@github.com:YOUR-USERNAME/my-project.git
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Refresh GitHub. &lt;strong&gt;Your code is online!&lt;/strong&gt; 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  The Regular Workflow
&lt;/h3&gt;

&lt;p&gt;From now on, it's just:&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="c"&gt;# Make changes to your files&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Describe what you changed"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three commands. That's your daily routine.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Pull Changes
&lt;/h2&gt;

&lt;p&gt;Someone else updated the project? You edited on GitHub? Working from another computer?&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Done. You now have the latest version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pro tip:&lt;/strong&gt; Always &lt;code&gt;git pull&lt;/code&gt; before you start working!&lt;/p&gt;

&lt;h3&gt;
  
  
  When Conflicts Happen
&lt;/h3&gt;

&lt;p&gt;Sometimes you and someone else edit the same line. Git shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;HEAD&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Your version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;=======&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Their version&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;origin&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix it:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose which version to keep (or combine them)&lt;/li&gt;
&lt;li&gt;Delete those marker lines (&lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt;, &lt;code&gt;=======&lt;/code&gt;, &lt;code&gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Save, then:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Resolve conflict"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Conflicts are normal. Don't stress!&lt;/p&gt;




&lt;h2&gt;
  
  
  Command Cheat Sheet
&lt;/h2&gt;

&lt;p&gt;The ones you'll actually use:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"What changed?"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"Track all changes"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git commit -m "..."&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"Save snapshot"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"Upload to GitHub"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"Download updates"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git log --oneline&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;"Show history"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Undo Mistakes
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git restore &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo changes to a file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git restore --staged &amp;lt;file&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unstage a file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;git reset HEAD~1&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Undo last commit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Common Mistakes (And Fixes)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;❌ Forgot to commit before pushing&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add missing commit"&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;❌ Didn't pull first&lt;/strong&gt;&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
&lt;span class="c"&gt;# Fix any conflicts if needed&lt;/span&gt;
git push
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;❌ Committed passwords&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Delete them, then:&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;echo&lt;/span&gt; &lt;span class="s2"&gt;"secrets.txt"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
git add .gitignore
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Ignore sensitive files"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Safety:&lt;/strong&gt; Never lose work again&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence:&lt;/strong&gt; Experiment without fear of breaking things&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration:&lt;/strong&gt; Work with teams smoothly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portfolio:&lt;/strong&gt; Show your projects on GitHub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Career:&lt;/strong&gt; Every dev job uses Git&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;You know enough to start using Git daily. Just apply it to everything you build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Personal projects&lt;/li&gt;
&lt;li&gt;School assignments&lt;/li&gt;
&lt;li&gt;Practice exercises&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The best way to learn? Use it!&lt;/p&gt;




&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;You now know how to install Git, connect it to GitHub, track your changes and collaborate with others. These are the fundamentals that every developer uses daily.&lt;/p&gt;

&lt;p&gt;The key is to start small. Pick a project - any project - and start committing. Make mistakes. Break things. That's how you learn. Git has your back because you can always go back to a working version.&lt;/p&gt;

&lt;p&gt;Remember: the best developers aren't the ones who never make mistakes. They're the ones who know how to recover from them. And with Git, recovery is always just one command away.&lt;/p&gt;

&lt;p&gt;Now stop reading and start coding. Your first commit is waiting! 💻&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's the first project you're going to put on GitHub? Or if you've already started using Git, what was your biggest "aha!" moment? Share in the comments below - I'd love to hear your Git journey!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>datascience</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
