<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Suzanne Orido</title>
    <description>The latest articles on DEV Community by Suzanne Orido (@suzanne_orido).</description>
    <link>https://dev.to/suzanne_orido</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3709650%2F5178a150-6d4a-4e86-a7e4-77e004e6b4dd.jpg</url>
      <title>DEV Community: Suzanne Orido</title>
      <link>https://dev.to/suzanne_orido</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/suzanne_orido"/>
    <language>en</language>
    <item>
      <title>Connecting Power BI to SQL Databases</title>
      <dc:creator>Suzanne Orido</dc:creator>
      <pubDate>Mon, 07 Sep 2026 12:08:00 +0000</pubDate>
      <link>https://dev.to/suzanne_orido/connecting-power-bi-to-sql-databases-5e99</link>
      <guid>https://dev.to/suzanne_orido/connecting-power-bi-to-sql-databases-5e99</guid>
      <description>&lt;h1&gt;
  
  
  Connecting Power BI to SQL Databases
&lt;/h1&gt;

&lt;p&gt;A practical guide to integrating Power BI Desktop with local PostgreSQL and cloud-hosted Aiven databases, including data modelling and why SQL still matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction: Power BI and SQL Databases&lt;/li&gt;
&lt;li&gt;Connecting to a Local PostgreSQL Database&lt;/li&gt;
&lt;li&gt;Connecting to Aiven Cloud PostgreSQL&lt;/li&gt;
&lt;li&gt;Loading Tables and Creating Relationships&lt;/li&gt;
&lt;li&gt;Why SQL Skills Matter for Power BI Analysts&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Introduction: Power BI and SQL Databases
&lt;/h2&gt;

&lt;p&gt;Microsoft Power BI is one of the leading business intelligence platforms in use today. It enables organisations of all sizes to transform raw data into interactive dashboards, reports, and visualisations that help decision-makers act on evidence rather than intuition. From tracking monthly sales performance to monitoring operational KPIs in real time, Power BI sits at the centre of how modern businesses consume their data.&lt;/p&gt;

&lt;p&gt;Power BI is available in several forms. Power BI Desktop is the Windows application used to build reports and data models. Power BI Service is the cloud-based platform where those reports are published and shared across an organisation. Together, they cover the full lifecycle of analytical work — from raw data connection to executive-level dashboarding.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why connect Power BI to a database?
&lt;/h3&gt;

&lt;p&gt;While Power BI can import data from Excel files, CSV exports, and web APIs, these sources have significant limits. They are static, often out of date, and difficult to maintain at scale. A well-structured relational database, by contrast, is the authoritative source of truth for most business data. It stores transactions, customer records, inventory levels, and operational events with precision, consistency, and referential integrity.&lt;/p&gt;

&lt;p&gt;When Power BI connects directly to a database, analysts can query the freshest available data, apply complex filters at the database level, and avoid the overhead of manually exporting and re-importing flat files. The database handles storage and retrieval efficiently; Power BI handles visualisation and exploration. Each tool does what it does best.&lt;/p&gt;

&lt;h3&gt;
  
  
  The role of SQL databases in analytical workflows
&lt;/h3&gt;

&lt;p&gt;SQL (Structured Query Language) databases, including PostgreSQL, Microsoft SQL Server, and MySQL, are the backbone of most enterprise data architectures. They organise data into tables with clearly defined schemas, enforce relationships between entities, and support powerful querying through the SQL language.&lt;/p&gt;

&lt;p&gt;PostgreSQL, in particular, is an open-source relational database widely used in both development and production environments. It supports advanced data types, complex joins, window functions, and JSON storage, making it a versatile choice for analytical workloads. Whether self-hosted on a local machine or managed in the cloud through platforms like Aiven, PostgreSQL integrates cleanly with Power BI.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Connecting to a Local PostgreSQL Database
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What this guide covers:&lt;/strong&gt; This guide walks through connecting Power BI to both a local PostgreSQL instance and a cloud-hosted Aiven database. It also covers data modelling with four linked tables — &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 concludes with a discussion of why SQL fluency is valuable for BI analysts.&lt;/p&gt;

&lt;p&gt;A local PostgreSQL database runs on the same machine as Power BI Desktop, or on a machine within your local network. This is the standard setup for development, testing, or environments where the data does not leave the building. The connection process requires no SSL configuration and is straightforward once PostgreSQL is running and a database exists.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before beginning, confirm the following are in place:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Power BI Desktop is installed (Windows only).&lt;/li&gt;
&lt;li&gt;PostgreSQL is installed, and the target database is created.&lt;/li&gt;
&lt;li&gt;The Npgsql PostgreSQL connector is installed. Power BI requires this driver to communicate with PostgreSQL. Download it from the official Npgsql releases page and install it before opening Power BI.&lt;/li&gt;
&lt;li&gt;You know the database name, a valid username, and its password.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step-by-step connection process
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Open Power BI Desktop&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Launch the application. On the start screen, click &lt;strong&gt;Get Data&lt;/strong&gt;. If you are already inside a report, navigate to &lt;strong&gt;Home → Get Data&lt;/strong&gt; in the ribbon.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Search for PostgreSQL Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the Get Data dialogue, type &lt;code&gt;PostgreSQL&lt;/code&gt; in the search box. 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%2Fgithub.com%2Fuser-attachments%2Fassets%2F66c1e737-5182-4c1e-a8da-52892d183edd" class="article-body-image-wrapper"&gt;&lt;img width="360" height="605" alt="image" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fuser-attachments%2Fassets%2F66c1e737-5182-4c1e-a8da-52892d183edd"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Enter the server and database details&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the connection dialogue, fill in two fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server&lt;/strong&gt; — enter &lt;code&gt;localhost&lt;/code&gt; for a local instance, or a hostname/IP address for a network server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt; — enter the exact name of the PostgreSQL database you want to connect to (for example, &lt;code&gt;assignment&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Leave the &lt;strong&gt;Data Connectivity mode&lt;/strong&gt; as &lt;strong&gt;Import&lt;/strong&gt; unless you specifically require DirectQuery.&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%2Fgithub.com%2Fuser-attachments%2Fassets%2Fa5db885c-5f30-4b0e-a6e4-5243c31fc8b3" class="article-body-image-wrapper"&gt;&lt;img width="315" height="160" alt="image" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fuser-attachments%2Fassets%2Fa5db885c-5f30-4b0e-a6e4-5243c31fc8b3"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Provide credentials&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Power BI will prompt for a username and password. Select &lt;strong&gt;Database&lt;/strong&gt; under the credential type dropdown, then enter your PostgreSQL username (often &lt;code&gt;postgres&lt;/code&gt;) and the corresponding password. Click &lt;strong&gt;Connect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — Select and load tables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Navigator pane will display all schemas and tables in the database. Check the tables you want to load — for example, &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;. Click &lt;strong&gt;Load&lt;/strong&gt; to import them directly, or &lt;strong&gt;Transform Data&lt;/strong&gt; to open the Power Query Editor first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connection flow:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Power BI Desktop] → [Get Data / PostgreSQL] → [Server &amp;amp; Credentials] → [Navigator] → [Load]
      Step 1                  Step 2                  Steps 3–4           Step 5        Final
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Figure 3 — Local PostgreSQL connection flow&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; If the connection fails with a driver error, install the Npgsql connector and restart Power BI Desktop before trying again.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  3. Connecting to Aiven Cloud PostgreSQL
&lt;/h2&gt;

&lt;p&gt;Aiven is a managed cloud database platform that hosts PostgreSQL (and other databases) on your choice of cloud provider — AWS, Google Cloud, or Azure. Connecting Power BI to an Aiven PostgreSQL instance follows the same general steps as a local connection, with two important differences: the connection details are specific to your Aiven service, and SSL must be used to encrypt the connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  Obtaining connection details from Aiven
&lt;/h3&gt;

&lt;p&gt;Log in to the Aiven Console and open your PostgreSQL service. On the service overview page, you will find all the information needed to establish a connection:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Parameter&lt;/th&gt;
&lt;th&gt;Where to find it&lt;/th&gt;
&lt;th&gt;Example value&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Host&lt;/td&gt;
&lt;td&gt;Service Overview → Connection Information&lt;/td&gt;
&lt;td&gt;&lt;code&gt;pg-abc123.aivencloud.com&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Port&lt;/td&gt;
&lt;td&gt;Next to the host, typically a custom port&lt;/td&gt;
&lt;td&gt;&lt;code&gt;15432&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;Listed under the service name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;defaultdb&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Username&lt;/td&gt;
&lt;td&gt;Connection Information section&lt;/td&gt;
&lt;td&gt;&lt;code&gt;avnadmin&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Password&lt;/td&gt;
&lt;td&gt;Click the eye icon or copy button&lt;/td&gt;
&lt;td&gt;&lt;em&gt;(hidden — copy directly)&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSL Certificate&lt;/td&gt;
&lt;td&gt;Download button in Connection Information&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ca.pem&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Download the CA certificate (&lt;code&gt;ca.pem&lt;/code&gt;) and save it to a location you can reference easily, such as &lt;code&gt;C:\certs\aiven-ca.pem&lt;/code&gt; on Windows.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why SSL certificates are required
&lt;/h3&gt;

&lt;p&gt;A cloud database is accessible over the public internet. Without encryption, data transmitted between Power BI and the Aiven server — including credentials and query results — would be visible to anyone monitoring the network. SSL (Secure Sockets Layer) / TLS (Transport Layer Security) encrypts the entire connection, preventing interception.&lt;/p&gt;

&lt;p&gt;The CA certificate serves a second purpose: it allows Power BI to verify that it is connecting to the genuine Aiven server and not an impostor. This is known as certificate verification, and it protects against man-in-the-middle attacks. Aiven requires SSL on all connections; it cannot be disabled.&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%2Fgithub.com%2Fuser-attachments%2Fassets%2F21ff2816-5ec8-4ca9-b472-840aa68fa81b" class="article-body-image-wrapper"&gt;&lt;img width="800" height="400" alt="image" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fuser-attachments%2Fassets%2F21ff2816-5ec8-4ca9-b472-840aa68fa81b"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-step: connecting via Power BI Desktop
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Open Get Data → PostgreSQL Database&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follow the same steps as the local connection: &lt;strong&gt;Home → Get Data → PostgreSQL Database → Connect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Enter the Aiven host and port&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Server&lt;/strong&gt; field, enter the full Aiven hostname followed by a colon and the port number:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pg-abc123.aivencloud.com:15432
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;strong&gt;Database&lt;/strong&gt; field, enter the database name (often &lt;code&gt;defaultdb&lt;/code&gt; unless you created a named database).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Expand Advanced Options and add the SSL certificate&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the connection dialogue, click &lt;strong&gt;Advanced Options&lt;/strong&gt; to reveal additional fields. In the &lt;strong&gt;Additional connection string parameters&lt;/strong&gt; box, enter the SSL certificate path in the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="py"&gt;sslmode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;verify-ca;sslrootcert=C:&lt;/span&gt;&lt;span class="se"&gt;\c&lt;/span&gt;&lt;span class="s"&gt;erts&lt;/span&gt;&lt;span class="se"&gt;\a&lt;/span&gt;&lt;span class="s"&gt;iven-ca.pem&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Power BI to use SSL, verify the server's certificate, and trust only certificates signed by the CA you downloaded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 — Enter credentials and connect&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Click &lt;strong&gt;OK&lt;/strong&gt;. When prompted, select &lt;strong&gt;Database authentication&lt;/strong&gt;, enter the Aiven username (typically &lt;code&gt;avnadmin&lt;/code&gt;) and password copied from the Aiven Console. Click &lt;strong&gt;Connect&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — Select tables in the Navigator&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Navigator pane will display the available tables. Select the required tables and click &lt;strong&gt;Load&lt;/strong&gt; or &lt;strong&gt;Transform Data&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The certificate path must use the correct syntax. On Windows, use double backslashes or forward slashes in the path. If the &lt;code&gt;ca.pem&lt;/code&gt; file is not found, Power BI will fail to connect with an SSL handshake error. Verify the file exists at the exact path specified.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  4. Loading Tables and Creating Relationships
&lt;/h2&gt;

&lt;p&gt;Once the connection is established, Power BI loads the selected tables into its internal data model. For this guide, the PostgreSQL database contains four tables organised around a retail business scenario:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Primary key&lt;/th&gt;
&lt;th&gt;Key columns&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&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;td&gt;
&lt;code&gt;first_name&lt;/code&gt;, &lt;code&gt;last_name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;registration_date&lt;/code&gt;, &lt;code&gt;membership_status&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;50 customer records with registration and membership data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&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;td&gt;
&lt;code&gt;product_name&lt;/code&gt;, &lt;code&gt;category&lt;/code&gt;, &lt;code&gt;price&lt;/code&gt;, &lt;code&gt;supplier&lt;/code&gt;, &lt;code&gt;stock_quantity&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;15 products across categories with pricing and supplier info&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;sale_id&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;customer_id&lt;/code&gt; (FK), &lt;code&gt;product_id&lt;/code&gt; (FK), &lt;code&gt;quantity_sold&lt;/code&gt;, &lt;code&gt;sale_date&lt;/code&gt;, &lt;code&gt;total_amount&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;15 transaction records from 2023–2024&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;product_id&lt;/code&gt; (FK)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;stock_quantity&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Current stock levels for each product&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  How Power BI auto-detects relationships
&lt;/h3&gt;

&lt;p&gt;After loading these tables, Power BI may automatically detect relationships based on matching column names and data types. In this schema, it will likely identify that &lt;code&gt;sales.customer_id&lt;/code&gt; references &lt;code&gt;customers.customer_id&lt;/code&gt;, and that &lt;code&gt;sales.product_id&lt;/code&gt; references &lt;code&gt;products.product_id&lt;/code&gt;. The &lt;code&gt;inventory&lt;/code&gt; table shares &lt;code&gt;product_id&lt;/code&gt; with &lt;code&gt;products&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To inspect and manage relationships, navigate to the &lt;strong&gt;Model view&lt;/strong&gt; in Power BI Desktop — the icon that looks like three connected boxes in the left sidebar. Here you can see a visual map of all tables and the lines connecting 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%2Fgithub.com%2Fuser-attachments%2Fassets%2F4ca81fc0-6d06-4cc1-bb1f-44bb3e1b48eb" class="article-body-image-wrapper"&gt;&lt;img width="285" height="177" alt="image" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fuser-attachments%2Fassets%2F4ca81fc0-6d06-4cc1-bb1f-44bb3e1b48eb"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating and editing relationships manually
&lt;/h3&gt;

&lt;p&gt;If Power BI does not detect relationships automatically, or if a detected relationship is incorrect, you can manage them manually. In the Model view, drag from a foreign key column in one table to the primary key in another. Power BI will draw the relationship line and ask you to confirm the cardinality and cross-filter direction.&lt;/p&gt;

&lt;p&gt;For this schema, the three key relationships are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;customers.customer_id&lt;/code&gt; → &lt;code&gt;sales.customer_id&lt;/code&gt; (one-to-many)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;products.product_id&lt;/code&gt; → &lt;code&gt;sales.product_id&lt;/code&gt; (one-to-many)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;products.product_id&lt;/code&gt; → &lt;code&gt;inventory.product_id&lt;/code&gt; (one-to-one)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What data modelling enables
&lt;/h3&gt;

&lt;p&gt;With relationships in place, Power BI treats the tables as a unified data model rather than isolated datasets. When you build a chart showing total sales revenue by product category, Power BI knows to join &lt;code&gt;sales&lt;/code&gt; to &lt;code&gt;products&lt;/code&gt; via &lt;code&gt;product_id&lt;/code&gt; to retrieve the category name. When filtering by customer membership status, it traverses the relationship from &lt;code&gt;customers&lt;/code&gt; to &lt;code&gt;sales&lt;/code&gt; automatically.&lt;/p&gt;

&lt;p&gt;This is the core principle of star schema data modelling: a central fact table (&lt;code&gt;sales&lt;/code&gt;) linked to dimension tables (&lt;code&gt;customers&lt;/code&gt;, &lt;code&gt;products&lt;/code&gt;) that describe the who, what, and when of each transaction. The &lt;code&gt;inventory&lt;/code&gt; table functions as a supplementary dimension providing current stock context alongside product data.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note on cross-filter direction:&lt;/strong&gt; By default, Power BI uses single-directional filtering; filters flow from the dimension table into the fact table. In most cases, this is correct. Avoid enabling bidirectional filtering unless you have a specific requirement, as it can produce unexpected aggregation results and slow report performance.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  5. Why SQL Skills Matter for Power BI Analysts
&lt;/h2&gt;

&lt;p&gt;Power BI's graphical interface makes it possible to build dashboards without writing a single line of SQL. But analysts who understand SQL bring a fundamentally different level of capability to their work. SQL is not a requirement for using Power BI — it is a requirement for using it well.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"An analyst who can write SQL is not just faster — they understand the data at a structural level that shapes every design decision they make in Power BI."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Four ways SQL strengthens Power BI work
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Precise data retrieval&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Rather than loading an entire table and filtering inside Power BI, an analyst with SQL knowledge writes a query that retrieves only the rows and columns needed. This reduces memory usage, speeds up refresh times, and keeps the data model lean.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Filtering at the source&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SQL &lt;code&gt;WHERE&lt;/code&gt; clauses filter data before it reaches Power BI. An analyst who understands this can avoid importing years of historical records when only the past 12 months are relevant to the dashboard — a significant difference at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Pre-aggregation and joins&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Complex calculations, such as monthly revenue per customer segment, or average order value by product category, can be computed in SQL before the data is loaded. This offloads processing to the database engine, which handles large aggregations far more efficiently than Power BI's in-memory model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Data preparation and quality&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SQL lets analysts clean and reshape data at the source — standardising date formats, handling nulls, concatenating name fields, or pivoting rows into columns — before the data ever reaches Power Query. This keeps the Power BI model simple and the transformation logic auditable.&lt;/p&gt;

&lt;h3&gt;
  
  
  SQL in the context of this schema
&lt;/h3&gt;

&lt;p&gt;With the &lt;code&gt;assignment&lt;/code&gt; database used throughout this guide, a Power BI analyst who understands SQL can write queries like the one below to pre-aggregate sales data before loading it, rather than importing all 15 raw transaction rows and computing totals inside DAX:&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;category&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;membership_status&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;revenue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&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;sale_id&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;transactions&lt;/span&gt;
&lt;span class="k"&gt;FROM&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;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&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;INNER&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="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;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;category&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;membership_status&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;revenue&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 produces a compact summary table — joined, grouped, and sorted, ready for Power BI to visualise. An analyst who cannot write this query must load three raw tables, build the join in Power Query, and compute the aggregations with DAX. The result is the same, but the path is longer, more error-prone, and harder to debug.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary: SQL and Power BI as complementary layers
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Storage &amp;amp; retrieval&lt;/td&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;td&gt;Tables, indexes, relationships, data integrity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transformation&lt;/td&gt;
&lt;td&gt;SQL&lt;/td&gt;
&lt;td&gt;Filtering, joining, aggregating, cleaning at source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modeling&lt;/td&gt;
&lt;td&gt;Power BI Desktop&lt;/td&gt;
&lt;td&gt;Star schema, relationships, DAX measures&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Visualisation&lt;/td&gt;
&lt;td&gt;Power BI Desktop / Service&lt;/td&gt;
&lt;td&gt;Dashboards, reports, interactive charts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;SQL and Power BI are not competing tools; they are complementary layers in the same analytical pipeline. SQL handles structured retrieval and transformation at the database level. Power BI handles interactive visualisation and self-service exploration at the consumer level. Fluency in both means the analyst decides, with full awareness, where each operation belongs.&lt;/p&gt;

</description>
      <category>database</category>
      <category>postgres</category>
      <category>sql</category>
    </item>
    <item>
      <title>Mastering SQL Joins and Window Functions: A Comprehensive Guide</title>
      <dc:creator>Suzanne Orido</dc:creator>
      <pubDate>Mon, 07 Sep 2026 12:04:11 +0000</pubDate>
      <link>https://dev.to/suzanne_orido/mastering-sql-joins-and-window-functions-a-comprehensive-guide-a6l</link>
      <guid>https://dev.to/suzanne_orido/mastering-sql-joins-and-window-functions-a-comprehensive-guide-a6l</guid>
      <description>&lt;p&gt;SQL is the backbone of data manipulation in relational databases, and two of its most essential features are joins and window functions. Joins allow you to combine data from multiple tables, while window functions enable advanced calculations across rows without collapsing them into aggregates. Whether you're a beginner or an experienced data analyst, understanding these concepts can significantly enhance your querying skills. In this article, we'll dive deep into both, with explanations, examples, and tips.&lt;/p&gt;

&lt;p&gt;What Are SQL Joins?&lt;br&gt;
Joins are used to retrieve data from two or more tables based on a related column between them.&lt;/p&gt;

&lt;p&gt;Let's imagine a small e-commerce database with two tables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- customers&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;----+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;----+---------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Aisha&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Brian&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;Carla&lt;/span&gt;   &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;----+---------+&lt;/span&gt;

&lt;span class="c1"&gt;-- orders&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;----+-------------+--------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&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;amount&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;----+-------------+--------+&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;           &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;    &lt;span class="o"&gt;|&lt;/span&gt;
&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="c1"&gt;----+-------------+--------+&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice Carla (id 3) has no orders yet. Keep that in mind: it matters a lot once we get to joins.&lt;/p&gt;

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

&lt;p&gt;A &lt;strong&gt;join&lt;/strong&gt; combines rows from two or more tables based on a related column, in our case &lt;code&gt;customer_id&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;Returns only rows that match in &lt;strong&gt;both&lt;/strong&gt; tables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="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;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;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;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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Aisha | 250
Aisha | 100
Brian | 400
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Carla disappears entirely because she has no matching order. This is the most common join, but it silently drops unmatched rows, a frequent source of "wait, why is my data missing?" bugs.&lt;/p&gt;

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

&lt;p&gt;Returns &lt;strong&gt;all rows from the left table&lt;/strong&gt;, plus matches from the right table. Unmatched rows get &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="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&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;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="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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Aisha | 250
Aisha | 100
Brian | 400
Carla | NULL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now Carla shows up, with &lt;code&gt;NULL&lt;/code&gt; for &lt;code&gt;amount&lt;/code&gt;. Use &lt;code&gt;LEFT JOIN&lt;/code&gt; whenever you need to keep every record from your "main" table, matched data or not, e.g. "show me all customers, even ones who haven't ordered."&lt;/p&gt;

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

&lt;p&gt;The mirror image of &lt;code&gt;LEFT JOIN&lt;/code&gt;, it keeps all rows from the right table instead. It's less commonly used in practice; most people just flip the table order and use &lt;code&gt;LEFT JOIN&lt;/code&gt; instead, since it's easier to read.&lt;/p&gt;

&lt;h3&gt;
  
  
  FULL OUTER JOIN (MySQL workaround)
&lt;/h3&gt;

&lt;p&gt;MySQL doesn't support &lt;code&gt;FULL OUTER JOIN&lt;/code&gt; natively. You simulate it with &lt;code&gt;UNION&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="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;orders&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;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="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;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="k"&gt;UNION&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;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;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;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="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;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you every row from both tables, matched where possible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quick rule of thumb:&lt;/strong&gt; if you're not sure which join to use, ask "do I want to keep unmatched rows, and from which table?" That answer picks your join for you.&lt;/p&gt;

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

&lt;p&gt;Joins combine tables. &lt;strong&gt;Window functions&lt;/strong&gt; let you do calculations &lt;em&gt;across a set of rows&lt;/em&gt;, like running totals or rankings, &lt;strong&gt;without collapsing them into a single row&lt;/strong&gt; (which is what &lt;code&gt;GROUP BY&lt;/code&gt; does).&lt;/p&gt;

&lt;p&gt;The basic shape:&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="n"&gt;SOME_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="k"&gt;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="k"&gt;column&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PARTITION BY&lt;/code&gt; splits your data into groups (like &lt;code&gt;GROUP BY&lt;/code&gt;, but without merging rows).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ORDER BY&lt;/code&gt; decides the order within each group, which matters for ranking and running totals.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Assigns a unique, sequential number to each row within a partition.&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;customer_id&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;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;customer_id&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;amount&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;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This numbers each customer's orders from biggest to smallest, handy for finding "each customer's top order."&lt;/p&gt;

&lt;h3&gt;
  
  
  RANK() and DENSE_RANK()
&lt;/h3&gt;

&lt;p&gt;Similar to &lt;code&gt;ROW_NUMBER()&lt;/code&gt;, but they handle ties differently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;RANK()&lt;/code&gt;: ties share a rank, but leaves a gap afterward (1, 1, 3).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DENSE_RANK()&lt;/code&gt;: ties share a rank, no gap (1, 1, 2).
&lt;/li&gt;
&lt;/ul&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;customer_id&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;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;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;amount&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;overall_rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Running Totals with SUM()
&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="n"&gt;customer_id&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="k"&gt;SUM&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;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;customer_id&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;id&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;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Aisha, this gives 250, then 350 (250+100), a running total per customer, without needing a self-join or subquery.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparing Rows with LAG() and LEAD()
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;LAG()&lt;/code&gt; looks at the &lt;em&gt;previous&lt;/em&gt; row; &lt;code&gt;LEAD()&lt;/code&gt; looks at the &lt;em&gt;next&lt;/em&gt; row, great for comparing an order to the one before it.&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;customer_id&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="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;customer_id&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;id&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;previous_amount&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;orders&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Joins vs. Window Functions: When to Use Which
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Use case&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Combining data from two+ tables&lt;/td&gt;
&lt;td&gt;JOIN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Keeping all rows from one table regardless of matches&lt;/td&gt;
&lt;td&gt;LEFT JOIN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ranking rows within groups&lt;/td&gt;
&lt;td&gt;ROW_NUMBER() / RANK()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Running totals, moving averages&lt;/td&gt;
&lt;td&gt;Window function with SUM()/AVG()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comparing a row to the previous/next one&lt;/td&gt;
&lt;td&gt;LAG() / LEAD()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collapsing rows into one summary row per group&lt;/td&gt;
&lt;td&gt;GROUP BY (not a window function)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The key mental model: &lt;strong&gt;joins add columns from other tables; window functions add calculations across rows you already have, without losing any of them.&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Start by getting comfortable with &lt;code&gt;INNER JOIN&lt;/code&gt; and &lt;code&gt;LEFT JOIN&lt;/code&gt;, since they cover the vast majority of real-world queries. Once those feel natural, window functions like &lt;code&gt;ROW_NUMBER()&lt;/code&gt; and running &lt;code&gt;SUM()&lt;/code&gt; will feel like a natural next step rather than dark magic.&lt;/p&gt;

&lt;p&gt;Try rewriting a &lt;code&gt;GROUP BY&lt;/code&gt; query you've written before using a window function instead. It's one of the fastest ways to make the concept click.&lt;/p&gt;

&lt;p&gt;Happy querying! 🚀&lt;/p&gt;

</description>
      <category>data</category>
      <category>database</category>
      <category>sql</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Schemas in Power BI: Designing Models That Perform</title>
      <dc:creator>Suzanne Orido</dc:creator>
      <pubDate>Wed, 04 Feb 2026 10:14:10 +0000</pubDate>
      <link>https://dev.to/suzanne_orido/schemas-in-power-bi-designing-models-that-perform-4jhe</link>
      <guid>https://dev.to/suzanne_orido/schemas-in-power-bi-designing-models-that-perform-4jhe</guid>
      <description>&lt;p&gt;Power BI is a business intelligence and data visualization platform developed by Microsoft. It is used to connect to data from multiple sources, model that data, and produce interactive reports and dashboards for analysis and decision-making.&lt;br&gt;
In the world of business intelligence, data modeling is the "blueprint" that determines whether a Power BI report will be a high-performance engine or a slow, confusing mess.&lt;/p&gt;

&lt;p&gt;This article goes into detail on what data models are, why they are important in Power BI, and how to use star schemas and snowflake schemas when designing accurate data models.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is a data model?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;It is a visual representation of how different pieces of information relate to one another within a system. &lt;br&gt;
Think of a data model as a map that defines how your information is stored, connected, and filtered. Without this map, Power BI has to guess how your tables relate, which often leads to errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key components of a Data Model:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Tables&lt;/strong&gt;: These are the containers for your data. In a good model, these are split into Fact tables (the numbers/metrics) and Dimension tables (the descriptive context).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Fact Tables&lt;/strong&gt;&lt;br&gt;
They store the measurable business events that an organization wants to analyze. Each row represents an occurrence of something that happened, at a defined level of detail. Facts answer “how much,” “how many,” or “how often.&lt;br&gt;&lt;br&gt;
A fact table contains dimension key columns that relate to dimension tables and numeric measure columns. The dimension key columns determine the dimensionality of a fact table, while the dimension key values determine the granularity of a fact table.&lt;/p&gt;

&lt;p&gt;Some key characteristics include: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Large row counts&lt;/li&gt;
&lt;li&gt;Numeric, aggregatable columns&lt;/li&gt;
&lt;li&gt;Foreign keys linking to dimension tables&lt;/li&gt;
&lt;li&gt;One clear grain per table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Dimension Tables&lt;/strong&gt;&lt;br&gt;
They store the descriptive context used to filter, group, and explain measures in fact tables. They answer “who,” “what,” “where,” and “when.”&lt;/p&gt;

&lt;p&gt;Some key characteristics include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Smaller than fact tables&lt;/li&gt;
&lt;li&gt;Mostly categorical or textual attributes&lt;/li&gt;
&lt;li&gt;One primary key&lt;/li&gt;
&lt;li&gt;Referenced by fact tables through foreign keys&lt;/li&gt;
&lt;li&gt;Rarely aggregated&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Relationships in Power BI&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;Relationships in Power BI define how tables interact.&lt;/em&gt; They control which rows are included in a calculation. If relationships are wrong, results are wrong, regardless of visuals or DAX.&lt;/p&gt;

&lt;p&gt;Common relationship types include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One-to-many: standard and preferred (dimension → fact)
Example:
One Product → many Sales rows&lt;/li&gt;
&lt;li&gt;One-to-one: rare, use cautiously
Example:
Employee details are split across two tables&lt;/li&gt;
&lt;li&gt;Many-to-many: last resort, high risk
Example:
Customers belonging to multiple segments&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding Star Schema
&lt;/h2&gt;

&lt;p&gt;A star schema is a data modelling structure where a central fact table is directly connected to multiple dimension tables, forming a star-like layout. It is the preferred schema for Power BI and most analytical systems.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structure&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One fact table at the center&lt;/li&gt;
&lt;li&gt;Dimension tables radiating outward&lt;/li&gt;
&lt;li&gt;Each dimension connects to the fact with a one-to-many relationship&lt;/li&gt;
&lt;li&gt;No relationships between dimension tables&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How it works&lt;/strong&gt;&lt;br&gt;
The fact table stores business events. Dimension tables provide descriptive context. Filters flow from dimensions to the fact, ensuring correct aggregation and predictable results.&lt;br&gt;
Usually, fact tables represent the "many" aspect of a relationship, while dimension tables represent the "one" aspect. &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%2Fm36ktgx1gk0dt50m5ttk.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%2Fm36ktgx1gk0dt50m5ttk.png" alt=" " width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Snowflake Schema
&lt;/h2&gt;

&lt;p&gt;A snowflake schema is a data modelling structure in which dimension tables are normalized into multiple related tables rather than being stored as a single, flat dimension. The resulting layout resembles a snowflake rather than a star.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Structure&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One central fact table&lt;/li&gt;
&lt;li&gt;A dimension connected to the fact&lt;/li&gt;
&lt;li&gt;That dimension is further split into sub-dimensions&lt;/li&gt;
&lt;li&gt;Multiple joins required to reach descriptive attributes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;When they appear in Power BI&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When importing data directly from normalized source systems&lt;/li&gt;
&lt;li&gt;When modelling is not intentionally redesigned for analytics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although this reduces redundancy, too much snowflaking is discouraged because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It increases query complexity.&lt;/li&gt;
&lt;li&gt;It requires more joins.&lt;/li&gt;
&lt;li&gt;It may slow down performance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Snowflake schemas are storage-efficient. Star schemas are analytics-efficient.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  The importance of good data modelling
&lt;/h2&gt;

&lt;p&gt;Good data modelling is critical because it determines whether the analysis is correct, fast, and repeatable. Visuals and calculations sit on top of the model; they cannot fix structural errors beneath it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Accuracy&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
A good model enforces correct filter flow and aggregation. Measures return the same result regardless of visual layout. Poor models cause double-counting and inconsistent totals.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Performance&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Power BI’s engine is optimized for star schemas and simple relationships. Clean models reduce joins, improve compression, and deliver faster query execution. Bad models scale poorly as data grows.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Simplicity&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Well-modelled data requires fewer complex DAX expressions. Business logic lives in the model, not in workaround calculations. This reduces error rates and maintenance costs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Consistency&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Metrics are defined once and reused everywhere. Reports built by different authors produce the same numbers. This is essential for organizational trust.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Good models support new measures, dimensions, and visuals without redesign. Poor models collapse under change and require rewrites.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision quality&lt;/strong&gt;&lt;br&gt;
Executives act on reported numbers. Incorrect models produce confident but wrong answers. That is operational risk.&lt;/p&gt;

&lt;p&gt;In Power BI, data modelling is not preparation work. It is the core analytical task.&lt;/p&gt;

&lt;p&gt;In conclusion, data modelling is what makes Power BI reports work correctly. When data is well organized into fact and dimension tables with clear relationships, reports are fast, and numbers are accurate. Poor modelling leads to slow reports and wrong results. Good insights start with a good data model.&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>dataengineering</category>
      <category>microsoft</category>
      <category>performance</category>
    </item>
    <item>
      <title>Beginner-friendly introduction to MS Excel for Data Analytics</title>
      <dc:creator>Suzanne Orido</dc:creator>
      <pubDate>Sun, 25 Jan 2026 18:12:59 +0000</pubDate>
      <link>https://dev.to/suzanne_orido/beginner-friendly-introduction-to-ms-excel-for-data-analytics-4pjb</link>
      <guid>https://dev.to/suzanne_orido/beginner-friendly-introduction-to-ms-excel-for-data-analytics-4pjb</guid>
      <description>&lt;p&gt;Microsoft Excel is a spreadsheet application used to store, organize, and work with data. It helps turn raw data into useful information that supports decisions. It can be described as a digital table or grid for organizing, calculating, and analyzing information.&lt;/p&gt;

&lt;p&gt;While professional data analysts often use more advanced tools for big projects, Excel remains popular because it's accessible, familiar, and powerful enough for most everyday data tasks.&lt;/p&gt;

&lt;p&gt;In Excel, data is arranged in rows(horizontal groups of cells) and columns(vertical groups of cells). A cell is a single box in Excel's grid where you can store one piece of information.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Why use MS Excel for Data Analytics?&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;It's easy to learn and use, even for beginners&lt;/li&gt;
&lt;li&gt;It quickly organizes large amounts of data&lt;/li&gt;
&lt;li&gt;It performs fast calculations and basic statistical analysis&lt;/li&gt;
&lt;li&gt;It helps identify trends through charts and pivot tables&lt;/li&gt;
&lt;li&gt;It is widely available and accepted in most workplaces&lt;/li&gt;
&lt;li&gt;It allows quick insights without complex software&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Before analyzing data, it's important to understand the basic interface of Excel. This includes knowing the definition of the following:&lt;br&gt;
&lt;strong&gt;Row:&lt;/strong&gt; A horizontal group of cells labelled 1,2,3... on the left.&lt;br&gt;
&lt;strong&gt;Column:&lt;/strong&gt; A vertical group of cells labelled A,B,C... at the top.&lt;br&gt;
&lt;strong&gt;Cell:&lt;/strong&gt; Intersection of a row and a column.&lt;br&gt;
&lt;strong&gt;Workbook:&lt;/strong&gt; The entire Excel file that contains one or more sheets.&lt;br&gt;
&lt;strong&gt;Worksheet:&lt;/strong&gt; The individual page inside the workbook.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In this article, we will learn:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data cleaning: Removing duplicates, sorting data, filtering data&lt;/li&gt;
&lt;li&gt;Performing calculations using formulas&lt;/li&gt;
&lt;li&gt;Performing calculations using operators&lt;/li&gt;
&lt;li&gt;Data visualization: Using pivot tables, charts, and dashboards&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Data Cleaning&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Data cleaning is important because analysis is only as good as the data used. &lt;br&gt;
Some of the cleaning tasks include:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Removing duplicates&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This means identifying and deleting repeated entries in a dataset so that each record appears only once.&lt;br&gt;
To do this:&lt;br&gt;
Select the data or the column that may contain duplicates.&lt;br&gt;
Click the &lt;strong&gt;Data&lt;/strong&gt; tab.&lt;br&gt;
Choose &lt;strong&gt;Remove Duplicates.&lt;/strong&gt;&lt;br&gt;
Tick the column(s) Excel should check.&lt;br&gt;
Click OK.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmq30nwmypak80f7yopiv.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%2Fmq30nwmypak80f7yopiv.png" alt=" " width="799" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to clean text with Functions:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;TRIM()&lt;/code&gt; removes extra spaces&lt;br&gt;
&lt;code&gt;UPPER()&lt;/code&gt; and LOWER() standardize text formatting&lt;/p&gt;

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

&lt;p&gt;Sorting data in Excel means arranging data in a specific order to make it easier to understand and analyze.&lt;/p&gt;

&lt;p&gt;To do this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select the column or the entire dataset.&lt;/li&gt;
&lt;li&gt;Go to the Data tab.&lt;/li&gt;
&lt;li&gt;Click Sort A to Z (ascending) or Sort Z to A (descending).&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%2Fyqcr3aeu5xolaanpmvmj.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%2Fyqcr3aeu5xolaanpmvmj.png" alt=" " width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;&lt;em&gt;Filtering Data&lt;/em&gt;&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Filtering data in Excel displays only the rows that meet specific conditions while hiding the rest, allowing you to focus on certain values, dates, or number ranges without deleting any data.&lt;/p&gt;

&lt;p&gt;To do this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select your dataset.&lt;/li&gt;
&lt;li&gt;Go to the Data tab and click Filter.&lt;/li&gt;
&lt;li&gt;Small dropdown arrows appear in the column headers.&lt;/li&gt;
&lt;li&gt;Click a column’s dropdown arrow.&lt;/li&gt;
&lt;li&gt;Choose the criteria you want (specific values, dates, or number ranges).&lt;/li&gt;
&lt;li&gt;Excel displays only the rows that meet the selected criteria, hiding the rest.&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%2Fpukh8e38hz920w2efrzi.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%2Fpukh8e38hz920w2efrzi.png" alt=" " width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Performing calculations using formulas:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Click the cell where you want the result to appear.&lt;br&gt;
Type an equal sign &lt;code&gt;(=)&lt;/code&gt; to start the formula.&lt;br&gt;
Enter the calculation using numbers, cell references, and operators (like &lt;code&gt;+&lt;/code&gt;, &lt;code&gt;-&lt;/code&gt;, &lt;code&gt;*&lt;/code&gt;, &lt;code&gt;/&lt;/code&gt;). For example: &lt;code&gt;=A1+B1&lt;/code&gt; or &lt;code&gt;=C2*D2&lt;/code&gt;.&lt;br&gt;
Press Enter to see the result.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;=SUM(A2:A877)&lt;/code&gt; → Adds all numbers in the range&lt;br&gt;
&lt;code&gt;=AVERAGE(A2:A877)&lt;/code&gt; → Calculates the average&lt;br&gt;
&lt;code&gt;=MIN(A2:A877)&lt;/code&gt; → Finds the smallest value&lt;br&gt;
&lt;code&gt;=MAX(A2:A877)&lt;/code&gt; → Finds the largest value&lt;br&gt;
&lt;code&gt;=COUNT(A2:A877)&lt;/code&gt; → Counts numeric values&lt;br&gt;
&lt;code&gt;=COUNTA(A2:A877)&lt;/code&gt; → Counts all non-empty cells&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Performing calculations using operators:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;+&lt;/code&gt; → Addition e.g., &lt;code&gt;=A1+B1&lt;/code&gt;&lt;br&gt;
&lt;code&gt;-&lt;/code&gt; → Subtraction e.g., &lt;code&gt;=A1-B1&lt;/code&gt;&lt;br&gt;
&lt;code&gt;*&lt;/code&gt; → Multiplication e.g., &lt;code&gt;=A1*B1&lt;/code&gt; &lt;br&gt;
&lt;code&gt;/&lt;/code&gt; → Division e.g., &lt;code&gt;=A1/B1&lt;/code&gt;&lt;br&gt;
&lt;code&gt;^&lt;/code&gt; → Exponentiation / Power e.g., &lt;code&gt;=A1^B1&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Data Visualization&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Pivot Tables&lt;/strong&gt;&lt;br&gt;
A pivot table is an Excel tool used to quickly summarize and analyze large amounts of data.&lt;/p&gt;

&lt;p&gt;It works by reorganizing data to show totals, averages, counts, or comparisons without changing the original dataset.&lt;/p&gt;

&lt;p&gt;How to create a Pivot Table:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select your dataset.&lt;/li&gt;
&lt;li&gt;Go to the Insert tab and click PivotTable.&lt;/li&gt;
&lt;li&gt;Choose whether to place the pivot table in a new worksheet or the existing worksheet.&lt;/li&gt;
&lt;li&gt;Click OK.&lt;/li&gt;
&lt;li&gt;In the PivotTable Field List, drag fields into Rows, Columns, Values, or Filters to arrange and summarize your data.&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%2F9sohfthmzmwbndbr60vp.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%2F9sohfthmzmwbndbr60vp.png" alt=" " width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Charts&lt;/strong&gt;&lt;br&gt;
A chart in Excel is a visual representation of data, like bars, lines, or pie slices, that makes patterns and trends easier to understand.&lt;/p&gt;

&lt;p&gt;To create a chart:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select the data you want to visualize.&lt;/li&gt;
&lt;li&gt;Go to the Insert tab.&lt;/li&gt;
&lt;li&gt;Choose the chart type you want (e.g., Column, Line, Pie, Bar).&lt;/li&gt;
&lt;li&gt;Click the chart style, and Excel inserts it into your worksheet.&lt;/li&gt;
&lt;li&gt;Customize the chart using chart tools (titles, labels, colors) if needed.&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%2Fecc7tx4ev1vc6b3wn3uj.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%2Fecc7tx4ev1vc6b3wn3uj.png" alt=" " width="799" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dashboards&lt;/strong&gt;&lt;br&gt;
A dashboard in Excel is a single screen or sheet that displays key information and metrics from your data in a clear, visual way using charts, tables, and pivot tables.&lt;/p&gt;

&lt;p&gt;An Excel dashboard typically consists of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Charts – Bar, line, pie, or combo charts to visualize trends and comparisons.&lt;/li&gt;
&lt;li&gt;Pivot Tables – Summarize large datasets into totals, averages, counts, or other key metrics.&lt;/li&gt;
&lt;li&gt;Tables – Organized data or key figures for reference.&lt;/li&gt;
&lt;li&gt;Slicers and Filters – Interactive tools to quickly view specific data.&lt;/li&gt;
&lt;li&gt;Key Performance Indicators (KPIs) – Numbers, percentages, or symbols that show performance at a glance.&lt;/li&gt;
&lt;li&gt;Text Boxes / Labels – Titles, headings, or explanations for clarity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With that, you now know the basics and can Excel in data analytics. Cheers! 😄&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv52jra7xqbj6lctk0az.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdv52jra7xqbj6lctk0az.gif" alt=" " width="498" height="373"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Git and GitHub</title>
      <dc:creator>Suzanne Orido</dc:creator>
      <pubDate>Fri, 16 Jan 2026 19:31:14 +0000</pubDate>
      <link>https://dev.to/suzanne_orido/luxdev-assignment-1-21le</link>
      <guid>https://dev.to/suzanne_orido/luxdev-assignment-1-21le</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;What is Git?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Git is a distributed version control software system that is capable of managing versions of source code or data. It is often used to control source code by programmers who are developing software collaboratively.&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;Why is version control important?&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;It is a system that records every change made to a file or set of files over time so that you can recall specific versions later.&lt;/em&gt;&lt;br&gt;
The importance of version control includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Safety Net: You can "undo" mistakes by rolling back to any previous version of your project if something breaks.&lt;/li&gt;
&lt;li&gt;Teamwork: It allows multiple people to work on the same files simultaneously without overwriting each other's progress.&lt;/li&gt;
&lt;li&gt;Organization: It eliminates messy file naming (like final_v2_new.doc) by keeping one clean version while storing the history in the background.&lt;/li&gt;
&lt;li&gt;Branching: You can create "branches" to experiment with new ideas in isolation without risking the stability of the main project.&lt;/li&gt;
&lt;li&gt;Documentation: Every change is saved with a note (commit message), creating a detailed history of who changed what and why.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;How to push code to Github&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;To push your code to GitHub, you first need a repository (a project folder) hosted on their site. Here is the standard workflow using the terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Initial Upload (New Repository)
&lt;/h3&gt;

&lt;p&gt;Use this sequence to link a local project to a newly created GitHub repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Create Remote Repository:&lt;/strong&gt; On GitHub, create a new repository. Do not initialize with a README, .gitignore, or license if code already exists locally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Initialize Local Git:&lt;/strong&gt; Navigate to the project root and execute: &lt;code&gt;git init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Stage Files:&lt;/strong&gt; Add all files to the staging area: &lt;code&gt;git add.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Create First Commit:&lt;/strong&gt; Record the snapshot: &lt;code&gt;git commit -m "initial commit"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Define Main Branch:&lt;/strong&gt; Ensure the primary branch is named &lt;code&gt;main: git branch -M main&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Link Remote URL:&lt;/strong&gt; Connect the local repository to GitHub: &lt;code&gt;git remote add origin &amp;lt;github-repo-url&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execute Push:&lt;/strong&gt; Upload the code and set the upstream reference: &lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2.  Standard Synchronization (Existing Repository)
&lt;/h3&gt;

&lt;p&gt;Use this sequence for ongoing updates to a repository that is already linked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage Specific Changes:&lt;/strong&gt; &lt;code&gt;git add &amp;lt;file-name&amp;gt;&lt;/code&gt; (or &lt;code&gt;git add.&lt;/code&gt; for all changes)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commit:&lt;/strong&gt; &lt;code&gt;git commit -m "description of changes"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push:&lt;/strong&gt; &lt;code&gt;git push&lt;/code&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  &lt;strong&gt;How to pull code from GitHub&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;Code retrieval from GitHub is categorized into two primary operations: Initial Acquisition (Clone) and Synchronization (Pull)&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Clone:
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Used when the code doesn't exist on the local machine&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Identify Repository URL:&lt;/strong&gt; On the GitHub repository page, click the Code button and copy the URL (HTTPS or SSH).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initialize Download:&lt;/strong&gt; Open the terminal and execute: &lt;code&gt;git clone &amp;lt;repository-url&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Result:&lt;/strong&gt; Git creates a directory named after the repository, downloads all files, branches, and the full commit history, and configures the remote reference (origin).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Pull/Synchronization
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Used to update an existing local repository with changes from Github&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;- Navigate to Directory:&lt;/strong&gt; Enter the local project folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Execute Update:&lt;/strong&gt; Run the following command: &lt;code&gt;git pull origin &amp;lt;branch-name&amp;gt;&lt;/code&gt;  Example: &lt;code&gt;git pull origin main&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Mechanism:&lt;/strong&gt; This command executes two sub-operations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fetch:&lt;/strong&gt; Downloads remote data without altering local files.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Merge:&lt;/strong&gt; Integrates remote changes into the current active branch.&lt;/p&gt;

&lt;h1&gt;
  
  
  How to track changes using Git
&lt;/h1&gt;

&lt;p&gt;Git tracks changes by managing data between three logical states: &lt;strong&gt;the Working Directory (unsaved changes),&lt;/strong&gt; &lt;strong&gt;the Staging Area (prepared changes),&lt;/strong&gt; and the &lt;strong&gt;Local Repository (permanent history).&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Initialization
&lt;/h3&gt;

&lt;p&gt;Activate Git tracking in a project directory: &lt;code&gt;git init&lt;/code&gt; This creates a &lt;code&gt;.git&lt;/code&gt; subdirectory to store metadata and object databases.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. State Verification
&lt;/h3&gt;

&lt;p&gt;Determine the current status of files: &lt;code&gt;git status&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Untracked:&lt;/strong&gt; New files unknown to Git.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Modified:&lt;/strong&gt; Tracked files with unsaved changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Staged:&lt;/strong&gt; Changes moved to the Index, ready for the next snapshot.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Change Preparation (Staging)
&lt;/h3&gt;

&lt;p&gt;Select specific changes for inclusion in the next version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Single file: &lt;code&gt;git add &amp;lt;file-name&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All changes: &lt;code&gt;git add .&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interactive (partial file): &lt;code&gt;git add -p&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Version Finalization (Commit)
&lt;/h3&gt;

&lt;p&gt;Record the staged changes as a permanent snapshot: &lt;code&gt;git commit -m "Direct description of change"&lt;/code&gt; &lt;em&gt;Standard format:&lt;/em&gt; Use imperative mood (e.g., "Fix logic error" rather than "Fixed logic error").&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Change Analysis Tools
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Real-time Differences
&lt;/h4&gt;

&lt;p&gt;Analyze modifications before staging or committing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Unstaged changes:&lt;/strong&gt; &lt;code&gt;git diff&lt;/code&gt; (Compares working directory to staging area)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Staged changes:&lt;/strong&gt; &lt;code&gt;git diff --staged&lt;/code&gt; (Compares staging area to last commit)&lt;/p&gt;

&lt;h4&gt;
  
  
  Historical Review
&lt;/h4&gt;

&lt;p&gt;Inspect the chronological record of changes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Summary list:&lt;/strong&gt; &lt;code&gt;git log --oneline&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- Detailed patches:&lt;/strong&gt; &lt;code&gt;git log -p&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- File-specific history:&lt;/strong&gt; &lt;code&gt;git log -- &amp;lt;file-path&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Line-Level Attribution
&lt;/h4&gt;

&lt;p&gt;Identify when and by whom specific lines were altered: &lt;code&gt;git blame &amp;lt;file-name&amp;gt;&lt;/code&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>git</category>
      <category>softwaredevelopment</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
