<?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>Why Statistics Is the Backbone of Data Science: A Clinic Story</title>
      <dc:creator>Suzanne Orido</dc:creator>
      <pubDate>Mon, 05 Oct 2026 15:55:38 +0000</pubDate>
      <link>https://dev.to/suzanne_orido/why-statistics-is-the-backbone-of-data-science-a-clinic-story-10oc</link>
      <guid>https://dev.to/suzanne_orido/why-statistics-is-the-backbone-of-data-science-a-clinic-story-10oc</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Many people hear the word statistics and think of dense formulas and confusing charts. As a doctor moving into data science, I have come to see it differently. Programming languages and machine learning get the attention, but statistics is what makes the results trustworthy. It tells you whether a pattern is real, how sure you can be, and what to do next. To show this, I will walk through a made-up but realistic example from a clinic. The numbers are illustrative, not from a real study.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Scenario&lt;/strong&gt;&lt;br&gt;
A busy outpatient clinic notices that many patients with hypertension are missing their follow-up appointments. Missed follow-ups matter: uncontrolled blood pressure raises the risk of stroke and kidney disease, and every empty slot is a wasted opportunity for care. The clinic's analyst is asked a simple question: who is missing appointments, and what can we do about it?&lt;br&gt;
The data available includes age, diagnosis, number of previous visits, distance from the clinic, whether the patient received a reminder, and whether they attended. Thousands of rows, no obvious story. Statistics is how the story is found.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Describe What Is Happening&lt;/strong&gt;&lt;br&gt;
The first step is descriptive statistics: averages, counts and rates that summarise the data. Instead of reading thousands of rows, the analyst asks how the missed-appointment rate differs across groups.&lt;/p&gt;

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

&lt;p&gt;The output shows that 20% of patients under 40 missed appointments, 30% of those aged 40 to 64, and 50% of those aged 65 and above. A pattern that was invisible in the raw rows is now clear: older patients are the most likely to miss follow-up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Estimate Risk&lt;/strong&gt;&lt;br&gt;
Next comes probability. The question changes from "what happened?" to "how likely is it to happen again?" By comparing groups, the analyst can estimate the chance that a patient will miss an appointment, depending on their characteristics. Patients who live far away, who have missed a visit before, or who never received a reminder may each carry a higher probability. Knowing this lets the clinic focus its limited resources on the patients who need the most help.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Test the Idea Properly&lt;/strong&gt;&lt;br&gt;
Suppose the clinic believes that sending SMS reminders will improve attendance. It tries them with one group and compares them with a group that gets none. Imagine 60 of 100 patients attend without reminders, and 78 of 100 attend with reminders. That looks like an improvement, but could it just be chance?&lt;br&gt;
This is what hypothesis testing answers. &lt;br&gt;
A chi-square test checks whether the difference is larger than random variation would plausibly produce.&lt;/p&gt;

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

&lt;p&gt;The p-value comes out well below 0.05, so the difference is unlikely to be due to chance alone. The clinic now has evidence, not just an impression, to justify investing in reminders. In medicine we make the same distinction between an anecdote and a trial result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Predict Who Is at Risk&lt;/strong&gt;&lt;br&gt;
Statistics also underlies machine learning. &lt;br&gt;
A model such as logistic regression can use many factors at once (age, distance, past attendance, reminders) and produce a risk score for each patient. The clinic can then call high-risk patients before their appointment, offer a telemedicine visit instead, or arrange transport. &lt;br&gt;
The model is not magic. It is statistics applied at scale, and its quality depends on the quality of the data and the care taken in checking it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Statistics Matters in Data Science
&lt;/h2&gt;

&lt;p&gt;• It summarises large datasets into something a human can read.&lt;br&gt;
• It reveals patterns that raw rows hide.&lt;br&gt;
• It measures uncertainty, so you know how far to trust a result.&lt;br&gt;
• It tests ideas before money and effort are committed.&lt;br&gt;
• It supports predictions that lead to earlier, better decisions.&lt;br&gt;
The same logic applies in banking, retail, education and technology. A model without sound statistical thinking can look impressive and still be wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Coding tools and AI models get most of the attention in data science, but they sit on top of statistics. In the clinic example, statistics found who was missing appointments, estimated their risk, showed that reminders actually worked, and powered a model to prevent missed care. For a clinician, none of this is foreign. We already weigh evidence, think in probabilities and ask whether a result could be chance. Statistics gives those habits a formal language, and learning it is one of the most valuable steps toward working with health data.&lt;/p&gt;

</description>
      <category>analytics</category>
      <category>data</category>
      <category>datascience</category>
    </item>
    <item>
      <title>Python for Data Analytics: A Doctor's Introduction</title>
      <dc:creator>Suzanne Orido</dc:creator>
      <pubDate>Mon, 05 Oct 2026 15:34:14 +0000</pubDate>
      <link>https://dev.to/suzanne_orido/python-for-data-analytics-a-doctors-introduction-6c4</link>
      <guid>https://dev.to/suzanne_orido/python-for-data-analytics-a-doctors-introduction-6c4</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Every clinic generates data: visit records, lab results, prescriptions, referrals. On its own, that data sits in files and systems doing very little. Data analytics is the practice of turning it into answers: which conditions are rising, which patients are being lost to follow-up, which clinics are overloaded. Python has become one of the most widely used tools for this work.&lt;br&gt;
As a doctor learning data science, I find it useful to explain Python through the situations healthcare workers already know. This article covers what Python is, the main libraries analysts rely on, how it is used to clean, analyse and visualise data, and where it applies in healthcare and beyond.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Python?&lt;/strong&gt;&lt;br&gt;
Python is a high-level, open-source programming language created by Guido van Rossum and released in 1991. Its code is designed to read almost like plain English, and it runs on Windows, macOS and Linux. It is free, and it is used far beyond data work, in web development, automation, cybersecurity and artificial intelligence.&lt;br&gt;
For a beginner, the practical benefit is that you spend your time thinking about the problem instead of fighting the syntax. For someone from a non-technical background, such as medicine, that matters a great deal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Analytics in Clinical Terms&lt;/strong&gt;&lt;br&gt;
Data analytics means collecting, cleaning, examining and interpreting data to support decisions. The four common types map neatly onto clinical thinking:&lt;br&gt;
• Descriptive: what happened? For example, how many malaria cases did the clinic see last month?&lt;br&gt;
• Diagnostic: why did it happen? For example, why did missed appointments rise in March?&lt;br&gt;
• Predictive: what is likely to happen? For example, which patients are at high risk of readmission?&lt;br&gt;
• Prescriptive: what should we do? For example, which clinics need extra staff before the rainy season?&lt;br&gt;
Python has tools for all four.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Python Works So Well for Analytics&lt;/strong&gt;&lt;br&gt;
• Readable syntax, so people from any background can learn it.&lt;br&gt;
• A large community, so almost any error message has already been solved on a forum.&lt;br&gt;
• Specialised libraries, which save you from writing common tasks from scratch.&lt;br&gt;
• Flexibility: the same language handles cleaning, statistics, charts, machine learning and automation.&lt;br&gt;
• Integration with databases, spreadsheets and cloud platforms.&lt;br&gt;
• Automation of repetitive jobs such as weekly reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Libraries That Do the Heavy Lifting&lt;/strong&gt;&lt;br&gt;
A library is a collection of pre-written code for a particular kind of task. These are the ones I find most important:&lt;br&gt;
• NumPy handles numerical work and arrays, and underpins most other libraries.&lt;br&gt;
• Pandas reads CSV and Excel files and organises data into tables called DataFrames. It is the everyday tool for cleaning and filtering, and the closest thing to a spreadsheet with far more power.&lt;br&gt;
• Matplotlib draws line graphs, bar charts, histograms and pie charts.&lt;br&gt;
• Seaborn builds on Matplotlib to produce polished statistical graphics such as heat maps and distribution plots.&lt;br&gt;
• Scikit-learn supports machine learning, such as classification and risk prediction.&lt;br&gt;
• TensorFlow and PyTorch are used for deep learning, such as medical image analysis and speech recognition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cleaning Data: The Step Everyone Underestimates
&lt;/h2&gt;

&lt;p&gt;Real-world data is messy. Anyone who has read handwritten notes or an inconsistent registry knows this. &lt;br&gt;
Duplicate patient entries, missing ages, dates stored as text and misspelled diagnoses are all normal. Cleaning comes before analysis, because conclusions drawn from unreliable data are unreliable.&lt;/p&gt;

&lt;p&gt;One clinical caution: missing data is not always random. A missing blood pressure may mean the measurement was never taken, which is itself information. Think about why a value is missing before filling it in or deleting it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Analysing and Visualising Data
&lt;/h2&gt;

&lt;p&gt;Once the data is clean, analysis can begin: totals, averages, comparisons between groups, and patterns over time.&lt;br&gt;
Visualisation matters because people absorb a chart faster than a table of numbers. A bar chart of weekly cases can show a rising outbreak at a glance, which is far harder to see in a spreadsheet of raw counts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Advantages and Limitations&lt;/strong&gt;&lt;br&gt;
Python saves time through automation, handles large datasets, reduces manual calculation errors and supports advanced modelling.&lt;br&gt;
It does have limits. It runs more slowly than languages such as C++, large datasets can use a lot of memory, and advanced areas like machine learning require real study. For most analytics work, though, these limits rarely get in the way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Beginners, Especially Clinicians, Should Learn It&lt;/strong&gt;&lt;br&gt;
• The syntax is forgiving.&lt;br&gt;
• Demand for Python skills is high across industries.&lt;br&gt;
• It opens career paths in analytics, AI, software development and health informatics.&lt;br&gt;
• Free tutorials, books and courses are plentiful.&lt;br&gt;
• It is useful for research: cleaning study data, running analyses and producing figures without depending on someone else.&lt;/p&gt;

&lt;p&gt;For clinicians, there is an extra reason. Health data is growing quickly, and the people who understand both the clinical context and the code are well placed to ask better questions and catch analyses that make no clinical sense.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Python is more than a programming language for me. It is a practical tool for turning raw records into evidence. Its readable syntax and strong libraries make it approachable for beginners, and its range makes it valuable to professionals in every field, including medicine. For anyone starting out, my advice is to begin with a small, real dataset, clean it, ask one question of it, and draw one chart. That is where the learning starts. &lt;/p&gt;

</description>
      <category>analytics</category>
      <category>datascience</category>
      <category>learning</category>
      <category>python</category>
    </item>
    <item>
      <title>My Experience Using SQL: DDL, DML, WHERE and CASE WHEN</title>
      <dc:creator>Suzanne Orido</dc:creator>
      <pubDate>Mon, 05 Oct 2026 14:42:07 +0000</pubDate>
      <link>https://dev.to/suzanne_orido/my-experience-using-sql-ddl-dml-where-and-case-when-16o5</link>
      <guid>https://dev.to/suzanne_orido/my-experience-using-sql-ddl-dml-where-and-case-when-16o5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Coming from a medical background, I am used to working with patient records, but I had never worked directly with the databases that store them. This week I wrote my first SQL queries, using DBeaver and PostgreSQL. At first, the commands felt like separate pieces that I could not fit together. With practice, they started to connect, and I realized how much can be done with just a few statements: build a table, fill it, change it, and pull out exactly what you need. In this article I cover the concepts I worked with: Data Definition Language (DDL), Data Manipulation Language (DML), the WHERE clause and CASE WHEN. My examples use a small clinic database instead of a generic one.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Definition Language (DDL)&lt;/strong&gt;&lt;br&gt;
DDL is the part of SQL that defines the structure of a database: its tables, columns and data types. Before any patient data can be stored, there has to be a place for it to live, and CREATE TABLE builds that place.&lt;/p&gt;

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

&lt;p&gt;This creates a patients table where each patient gets a unique ID, similar to a file number in a clinic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Manipulation Language (DML)&lt;/strong&gt;&lt;br&gt;
Where DDL builds the structure, DML works with the data inside it. The three commands I used most were INSERT, UPDATE and DELETE.&lt;br&gt;
INSERT adds new records:&lt;/p&gt;

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

&lt;p&gt;UPDATE changes existing records, and DELETE removes them. Both need a condition; otherwise, they affect every row in the table, which is a mistake worth avoiding early.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;The WHERE Clause&lt;/strong&gt;&lt;br&gt;
WHERE filters rows so that only those meeting a condition are returned. Instead of scanning a whole table, you ask a specific question, much like searching a register for one clinic's patients.&lt;/p&gt;

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

&lt;p&gt;The = operator finds exact matches, &amp;gt; finds values above a threshold, and BETWEEN selects a range.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CASE WHEN&lt;/strong&gt;&lt;br&gt;
CASE WHEN applies conditions and returns different results depending on which one is met. It works like clinical triage rules: if the patient meets this criterion, assign this category.&lt;/p&gt;

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

&lt;p&gt;This was the hardest concept for me. However, it helped me to read each WHEN line as an if statement and to notice that SQL checks them from top to bottom and stops at the first match. &lt;br&gt;
Once that clicked, I saw how useful it is for grouping data into meaningful categories.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>postgres</category>
      <category>sql</category>
    </item>
    <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>
