<?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: Gideon Kiprono</title>
    <description>The latest articles on DEV Community by Gideon Kiprono (@gideon_kiprono_bfdedde010).</description>
    <link>https://dev.to/gideon_kiprono_bfdedde010</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%2F3952212%2Faa7c3a6d-c93c-42bf-b03c-78a69896b986.jpg</url>
      <title>DEV Community: Gideon Kiprono</title>
      <link>https://dev.to/gideon_kiprono_bfdedde010</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gideon_kiprono_bfdedde010"/>
    <language>en</language>
    <item>
      <title>Python Data structures</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Thu, 22 Oct 2026 17:02:18 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/python-data-structures-172k</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/python-data-structures-172k</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When you go to a grocery store, you don't throw eggs, milk, and apples loosely into a single giant box. You instead put the eggs in a carton, the milk in a jug, and the apples in a bag. &lt;br&gt;
In programming, &lt;strong&gt;data structures&lt;/strong&gt; are those containers. They are specialized ways of organizing and storing data in your computer's memory so that you can &lt;em&gt;access&lt;/em&gt;, &lt;em&gt;sort&lt;/em&gt;, and &lt;em&gt;modify&lt;/em&gt; your information efficiently.&lt;/p&gt;
&lt;h2&gt;
  
  
  1. The Core Four Data Structures
&lt;/h2&gt;

&lt;p&gt;Python has four built-in data structures that handle almost every data organization task you will encounter.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lists
&lt;/h3&gt;

&lt;p&gt;A list is an ordered, mutable collection of items enclosed in square brackets &lt;code&gt;[]&lt;/code&gt;, with elements separated by commas.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ordered&lt;/strong&gt;: Items maintain their position and can be accessed using an index, starting from &lt;code&gt;0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutable&lt;/strong&gt;: Items can be added, removed, or modified after the list is created.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Allows duplicates&lt;/strong&gt;: A list can contain repeated values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supports different data types&lt;/strong&gt;: A list can contain strings, integers, floats, booleans, and other objects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Code Snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# =====================================
# UNDERSTANDING LISTS IN PYTHON
# =====================================

# 1. Creating a list
shopping_list = ["Milk", "Eggs", "Bread"]

print("Original List:", shopping_list)

# 2. ORDERED - Accessing items using indexes
print("\nFirst Item:", shopping_list[0])
print("Second Item:", shopping_list[1])

# 3. MUTABLE - Adding a new item
shopping_list.append("Butter")
print("\nAfter Adding Butter:", shopping_list)

# 4. MUTABLE - Modifying an existing item
shopping_list[1] = "Cheese"
print("After Replacing Eggs:", shopping_list)

# 5. MUTABLE - Removing an item
shopping_list.remove("Bread")
print("After Removing Bread:", shopping_list)

# 6. ALLOWS DUPLICATES
shopping_list.append("Milk")
print("\nAfter Adding Duplicate Milk:", shopping_list)

# 7. Checking the number of items
print("Total Items:", len(shopping_list))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Common List Operations in Python
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Python Code&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create&lt;/td&gt;
&lt;td&gt;&lt;code&gt;items = ["A", "B"]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a list.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access&lt;/td&gt;
&lt;td&gt;&lt;code&gt;items[0]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Gets the first item.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add&lt;/td&gt;
&lt;td&gt;&lt;code&gt;items.append("C")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Adds an item at the end of the list.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert&lt;/td&gt;
&lt;td&gt;&lt;code&gt;items.insert(1, "C")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inserts an item at a specified index.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modify&lt;/td&gt;
&lt;td&gt;&lt;code&gt;items[0] = "D"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changes an existing item.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Remove&lt;/td&gt;
&lt;td&gt;&lt;code&gt;items.remove("B")&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes the first matching item.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Delete&lt;/td&gt;
&lt;td&gt;&lt;code&gt;items.pop()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes and returns the last item.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Count&lt;/td&gt;
&lt;td&gt;&lt;code&gt;len(items)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Returns the number of items in the list.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt; Python uses &lt;code&gt;zero-based indexing&lt;/code&gt;, meaning the first item is at position 0, not 1.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tuples
&lt;/h3&gt;

&lt;p&gt;A tuple is an ordered, immutable collection of items, typically enclosed in parentheses &lt;code&gt;()&lt;/code&gt; and separated by &lt;code&gt;commas&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Unlike lists, &lt;code&gt;tuples cannot be modified after creation&lt;/code&gt;. This means you cannot add, remove, or replace individual elements within a tuple.&lt;/p&gt;

&lt;p&gt;Key characteristics of tuples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ordered&lt;/strong&gt;: Elements maintain their position and can be accessed using indexes, starting from 0.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Immutable&lt;/strong&gt;: Elements cannot be added, removed, or reassigned after the tuple is created.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Allows duplicates&lt;/strong&gt;: Tuples can contain repeated values.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supports different data types&lt;/strong&gt;: A tuple can store strings, integers, floats, and other Python objects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Supports unpacking&lt;/strong&gt;: Values can be assigned to individual variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Code Snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# =====================================
# UNDERSTANDING TUPLES IN PYTHON
# =====================================

# 1. Creating a tuple
# Fixed GPS coordinates (Latitude, Longitude)
nairobi_coords = (-1.218, 36.889)

print("Original Coordinates:", nairobi_coords)

# 2. ORDERED - Accessing elements by index
print("\nLatitude:", nairobi_coords[0])
print("Longitude:", nairobi_coords[1])

# 3. UNPACKING - Assigning values to variables
latitude, longitude = nairobi_coords

print("\nUnpacked Latitude:", latitude)
print("Unpacked Longitude:", longitude)

# 4. IMMUTABLE - Attempting to modify a tuple
try:
    nairobi_coords[0] = -1.300

except TypeError:
    print("\nERROR: Tuples cannot be modified!")

# 5. LENGTH - Counting elements
print("\nTotal Elements:", len(nairobi_coords))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Lists vs Tuples in Python
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;List &lt;code&gt;[]&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Tuple &lt;code&gt;()&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ordered&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mutable&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allows duplicates&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Indexing&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports different data types&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add/remove elements&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common use&lt;/td&gt;
&lt;td&gt;Shopping lists, inventory, changing data&lt;/td&gt;
&lt;td&gt;Coordinates, fixed configuration values, records&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key Takeaway:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lists:&lt;/strong&gt; Use when you need an ordered collection of items that can be modified.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tuples:&lt;/strong&gt; Use when you need an ordered collection whose elements should remain unchanged.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dictionaries
&lt;/h3&gt;

&lt;p&gt;A dictionary is a mutable collection of data stored in &lt;code&gt;key-value pairs&lt;/code&gt;, enclosed in curly braces &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Unlike lists and tuples, which primarily access elements using numerical indexes, dictionaries allow you to retrieve values using &lt;strong&gt;unique keys&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Each key acts as an identifier that maps to a corresponding value, similar to how a word in a physical dictionary maps to its definition.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key characteristics of dictionaries:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Key-value pairs&lt;/strong&gt;: Each element consists of a key and its associated value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutable&lt;/strong&gt;: You can add, update, or remove key-value pairs after creation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unique keys&lt;/strong&gt;: Duplicate keys are not allowed. Assigning a value to an existing key replaces its previous value.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Insertion ordered&lt;/strong&gt;: Dictionaries preserve the order in which keys are inserted (Python 3.7+).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexible data types&lt;/strong&gt;: Values can contain strings, numbers, lists, tuples, or even other dictionaries.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fast lookups&lt;/strong&gt;: Dictionaries typically provide efficient access to values through their keys.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Code snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# =====================================
# UNDERSTANDING DICTIONARIES IN PYTHON
# =====================================

# 1. Creating a dictionary
user_profile = {
    "username": "dev_alex",
    "age": 28,
    "clearance": "admin",
    "active": True
}

print("Original Profile:", user_profile)

# 2. ACCESSING VALUES USING KEYS
print("\nUsername:", user_profile["username"])
print("Clearance:", user_profile["clearance"])

# 3. SAFE ACCESS USING .get()
print("Department:", user_profile.get("department", "Not Assigned"))

# 4. MUTABLE - Adding a new key-value pair
user_profile["department"] = "Engineering"
print("\nAfter Adding Department:", user_profile)

# 5. MUTABLE - Updating an existing value
user_profile["clearance"] = "super_admin"
print("Updated Clearance:", user_profile["clearance"])

# 6. MUTABLE - Removing a key-value pair
user_profile.pop("age")
print("\nAfter Removing Age:", user_profile)

# 7. CHECKING IF A KEY EXISTS
if "username" in user_profile:
    print("\nUsername exists in the dictionary")

# 8. ITERATING THROUGH KEY-VALUE PAIRS
print("\n--- USER PROFILE DETAILS ---")

for key, value in user_profile.items():
    print(f"{key}: {value}")

# 9. COUNTING KEY-VALUE PAIRS
print("\nTotal Entries:", len(user_profile))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Lists vs Tuples vs Dictionaries in Python
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;List &lt;code&gt;[]&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Tuple &lt;code&gt;()&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Dictionary &lt;code&gt;{}&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ordered&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes (insertion order)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mutable&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allows duplicates&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Values: Yes; Keys: No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access elements&lt;/td&gt;
&lt;td&gt;Numerical index&lt;/td&gt;
&lt;td&gt;Numerical index&lt;/td&gt;
&lt;td&gt;Unique keys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports mixed data types&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add/remove elements&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common use&lt;/td&gt;
&lt;td&gt;Shopping lists, inventory&lt;/td&gt;
&lt;td&gt;Coordinates, fixed records&lt;/td&gt;
&lt;td&gt;User profiles, configurations, structured records&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key takeaway:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dictionaries are ideal when you want to store, organize, and retrieve related information using meaningful keys rather than numerical positions. &lt;/li&gt;
&lt;li&gt;They are widely used in Python applications, JSON processing, APIs, data engineering, and configuration management.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Sets
&lt;/h3&gt;

&lt;p&gt;A set is an &lt;code&gt;unordered, mutable collection of unique element&lt;/code&gt;s, typically enclosed in curly braces &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Unlike lists and tuples, &lt;code&gt;sets do not allow duplicate values&lt;/code&gt;. If an element appears more than once, Python automatically keeps only one occurrence.&lt;/p&gt;

&lt;p&gt;Sets are particularly useful for removing duplicates, checking membership, and performing mathematical operations such as unions, intersections, and differences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key characteristics of sets:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unordered&lt;/strong&gt;: Elements do not have fixed positions or numerical indexes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mutable&lt;/strong&gt;: You can add or remove elements after creating a set.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unique elements&lt;/strong&gt;: Duplicate values are automatically eliminated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No indexing&lt;/strong&gt;: You cannot access elements using positions such as my_set[0].&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hashable elements&lt;/strong&gt;: Set elements must be hashable, such as integers, strings, or tuples containing hashable values. Lists and dictionaries cannot be direct set elements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Efficient membership testing&lt;/strong&gt;: Sets are useful for quickly checking whether an item exists in a collection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Code snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# =====================================
# UNDERSTANDING SETS IN PYTHON
# =====================================

# 1. CREATING A SET
# Duplicate employee ID 101 is automatically removed
unique_ids = {101, 102, 103, 101}

print("Original Set:", sorted(unique_ids))

# 2. MUTABLE - Adding a new element
unique_ids.add(104)
print("\nAfter Adding 104:", sorted(unique_ids))

# 3. UNIQUE ELEMENTS - Adding a duplicate
unique_ids.add(102)
print("After Adding Duplicate 102:", sorted(unique_ids))

# 4. MUTABLE - Removing an element
unique_ids.remove(103)
print("\nAfter Removing 103:", sorted(unique_ids))

# 5. MEMBERSHIP TESTING
if 101 in unique_ids:
    print("\nEmployee ID 101 exists in the system.")

# 6. SET OPERATIONS
morning_shift = {101, 102, 105}
evening_shift = {102, 104, 106}

# UNION - All unique employees across both shifts
print("\nUnion:", sorted(morning_shift | evening_shift))

# INTERSECTION - Employees in both shifts
print("Intersection:", sorted(morning_shift &amp;amp; evening_shift))

# DIFFERENCE - Employees only in the morning shift
print("Difference:", sorted(morning_shift - evening_shift))

# 7. COUNTING UNIQUE ELEMENTS
print("\nTotal Unique IDs:", len(unique_ids))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I used sorted() to display the elements in ascending order, making the output easier to follow. It returns a sorted list without changing the original set. Sets themselves do not guarantee an iteration order.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparison of Python Collections
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;List &lt;code&gt;[]&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Tuple &lt;code&gt;()&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Dictionary &lt;code&gt;{}&lt;/code&gt;
&lt;/th&gt;
&lt;th&gt;Set &lt;code&gt;{}&lt;/code&gt;
&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Ordered&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mutable&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Allows Duplicates&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Keys: No, Values: Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Supports Indexing&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Key-based access&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add/Remove Elements&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Common Use&lt;/td&gt;
&lt;td&gt;Shopping lists, inventory&lt;/td&gt;
&lt;td&gt;Coordinates, fixed records&lt;/td&gt;
&lt;td&gt;User profiles, configurations&lt;/td&gt;
&lt;td&gt;Unique IDs, removing duplicates&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Key takeaway:&lt;/strong&gt; Use sets when you need to store unique values, remove duplicates, perform membership checks efficiently, or compare collections using mathematical set operations.&lt;/p&gt;

&lt;p&gt;For example, in data analytics, sets can help identify customers appearing in two datasets, detect unique product IDs, and compare records between different data sources.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Cheat Sheet: When to Use Each One
&lt;/h2&gt;

&lt;p&gt;Choosing the right structure keeps your program fast and free of bugs. Use this simple rule of thumb:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Data Structure&lt;/th&gt;
&lt;th&gt;Best Used For...&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;List&lt;/strong&gt; &lt;code&gt;[]&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Collections of data that need to stay in order and might change later.&lt;/td&gt;
&lt;td&gt;A list of task names in a to-do app.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Tuple&lt;/strong&gt; &lt;code&gt;()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Fixed, read-only data that must stay safe from accidental changes.&lt;/td&gt;
&lt;td&gt;Days of the week or config settings.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Dictionary&lt;/strong&gt; &lt;code&gt;{}&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Complex data that needs descriptive labels for fast lookups.&lt;/td&gt;
&lt;td&gt;A product page with price, color, and size.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Set&lt;/strong&gt; &lt;code&gt;{}&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Finding unique values or running math checks like finding overlaps.&lt;/td&gt;
&lt;td&gt;Tracking unique visitors to a website.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Practical Example: The Event Registration Manager
&lt;/h2&gt;

&lt;p&gt;Let's bring all four data structures together into a single program that manages guest attendance for a tech conference.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# ------------Event Registration Manager--------------------
# 1. TUPLE: Fixed event information that should never change
EVENT_INFO = ("Global Tech Summit", "Main Arena", "Day 1")

# 2. LIST: The active queue of arriving VIPs (we need order and flexibility)
vip_queue = ["Sarah", "Michael", "David"]
vip_queue.append("Elena")  # A new VIP arrives and is added to the end

# 3. DICTIONARY: Attendee profiles for quick lookup by ticket ID
attendee_profiles = {
    "TK-890": {"name": "Sarah", "type": "VIP", "checked_in": True},
    "TK-432": {"name": "John", "type": "Standard", "checked_in": False},
    "TK-112": {"name": "Michael", "type": "VIP", "checked_in": True}
}

# 4. SET: Tracking unique industries represented (no duplicates allowed!)
industries_present = {"Finance", "Healthcare", "Tech", "Finance"} # 'Finance' is repeated

# --- PROCESSING THE EVENT DATA ---
print(f"--- WELCOME TO THE {EVENT_INFO[0].upper()} ---")
print(f"Location: {EVENT_INFO[1]} | Schedule: {EVENT_INFO[2]}\n")

# Looking up a profile using a Dictionary Key
search_ticket = "TK-890"
guest_name = attendee_profiles[search_ticket]["name"]
print(f"Ticket Lookup: Ticket {search_ticket} belongs to {guest_name}.")

# Displaying the VIP order from our List
print(f"Next VIP in line to speak: {vip_queue[0]}")

# Displaying our Set (Notice how the duplicate 'Finance' is automatically gone)
print(f"Unique industries attending today: {industries_present}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tuple Protection&lt;/strong&gt;: &lt;code&gt;EVENT_INFO&lt;/code&gt; guarantees that nobody can accidentally overwrite the event name or location mid-program.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;List Flexibility&lt;/strong&gt;: &lt;code&gt;vip_queue&lt;/code&gt; preserves the order of arrivals and lets us pull or add speakers dynamically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dictionary Speed&lt;/strong&gt;: &lt;code&gt;attendee_profiles&lt;/code&gt; allows us to instantly pull up a specific person's profile using their ticket code without scanning the entire database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set Cleanliness&lt;/strong&gt;: &lt;code&gt;industries_present&lt;/code&gt; cleans our metadata automatically, ensuring we only see a list of unique industries without any repeating clutter.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Data structures are the architectural backbone of clean code. By mastering lists, tuples, dictionaries, and sets, you no longer just write code instructions—you map out data intentionally. This structural organization is exactly how massive platforms like Spotify manage playlists (lists), handle user accounts (dictionaries), and eliminate duplicate song recommendations (sets).&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>learning</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Python functions</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Thu, 22 Oct 2026 14:57:48 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/python-functions-5ad6</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/python-functions-5ad6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Think about a coffee machine. You do not need to know how the inner water tubes heat up or how the grinder operates every time you want an espresso. You simply press a button, give it coffee beans, and wait for your cup. In programming, functions are your code's buttons. They allow you to bundle up a complex block of code, give it a simple name, and reuse it whenever you want without typing it out over and over again.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Defining and calling functions
&lt;/h2&gt;

&lt;p&gt;To use a function, you must complete a two-step process: you build the button (&lt;strong&gt;define&lt;/strong&gt; it), and then you press the button (&lt;strong&gt;call&lt;/strong&gt; it).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Defining:&lt;/strong&gt; You use the keyword &lt;code&gt;def&lt;/code&gt; to tell Python you are making a function, followed by the &lt;code&gt;name&lt;/code&gt; of your choice and a colon (&lt;code&gt;:&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Calling:&lt;/strong&gt; To run that saved code later, you type the &lt;code&gt;function's name&lt;/code&gt; followed by parentheses &lt;code&gt;()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code Snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Defining the function
def send_alert():
    print("System warning: Storage space low!")

# Calling the function
send_alert()  # This runs the code inside send_alert
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; System Warning: Storage space low!&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Parameters and arguments
&lt;/h2&gt;

&lt;p&gt;Functions become incredibly powerful when you can pass data into them, allowing them to do different work depending on the inputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parameters&lt;/strong&gt;: These are the placeholder variables you write inside the parentheses when &lt;code&gt;defining&lt;/code&gt; the function. Think of them as the slots on the machine.&lt;br&gt;
&lt;strong&gt;Arguments&lt;/strong&gt;: These are the &lt;code&gt;actual, real values&lt;/code&gt; you pass into those slots when &lt;code&gt;calling&lt;/code&gt; the function.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code Snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 'username' is the parameter (the slot)
def greet_user(username):
    print(f"Welcome back, {username}!")

# "Alex" is the argument (the actual data filling the slot)
greet_user("Alex")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; Welcome back, Alex!&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Return values
&lt;/h2&gt;

&lt;p&gt;Sometimes, you don’t just want a function to print text to the screen. You want it to calculate an answer and &lt;strong&gt;hand that answer back&lt;/strong&gt; to the main program so you can use it somewhere else. We do this using the &lt;code&gt;return&lt;/code&gt; keyword.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Rule&lt;/em&gt;: Once a function hits a &lt;code&gt;return&lt;/code&gt; statement, it hands back the value and stops running immediately.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Code Snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def calculate_tax(amount):
    return amount * 0.08

# Saving the handed-back answer into a new variable
final_tax = calculate_tax(100)
print(f"Tax due: ${final_tax}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; Tax due: $8.0&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Scope
&lt;/h2&gt;

&lt;p&gt;Where you create a variable determines where you are allowed to use it. This concept is called &lt;strong&gt;scope&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Local Scope&lt;/strong&gt;: Variables created &lt;code&gt;inside a function&lt;/code&gt; belong exclusively to that function. They disappear as soon as the function finishes running, and the outside world cannot see them.&lt;br&gt;
&lt;strong&gt;Global Scope&lt;/strong&gt;: Variables created &lt;code&gt;outside all functions&lt;/code&gt; belong to the main program file. Any function can look at them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code Snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# =====================================
# UNDERSTANDING VARIABLE SCOPE IN PYTHON
# =====================================

# GLOBAL VARIABLE
global_msg = "I am a GLOBAL variable!"

def sample_function():

    # LOCAL VARIABLE
    local_msg = "I am a LOCAL variable!"

    print("--- INSIDE THE FUNCTION ---")

    # Accessing a global variable
    print("Global:", global_msg)

    # Accessing a local variable
    print("Local:", local_msg)


# 1. Call the function
sample_function()

# 2. Access variables outside the function
print("\n--- OUTSIDE THE FUNCTION ---")

# Global variable works
print("Global:", global_msg)

# Local variable causes an error
try:
    print("Local:", local_msg)

except NameError:
    print("ERROR: local_msg is not accessible outside the function!")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; &lt;/p&gt;

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

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

&lt;ul&gt;
&lt;li&gt;Trying to access a local variable outside its function causes a &lt;code&gt;NameError&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Notice that the try-except block prevents the program from crashing while demonstrating that local_msg is inaccessible outside the function.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  5. Practical example : The Automated Shipping Fee Calculator
&lt;/h2&gt;

&lt;p&gt;Let's combine definitions, parameters, return values, and scope rules into a practical project: an e-commerce shipping manager.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Code Snippet:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# --- GLOBAL SCOPE ---
# This variable lives outside and is accessible by any function below
COMPANY_TAX_RATE = 0.05

# 1. Defining a function with parameters and a return value
def calculate_shipping(weight, destination):
    # --- LOCAL SCOPE ---
    # This 'base_fee' variable only exists inside this specific function
    if destination.lower() == "international":
        base_fee = 15.00
    else:
        base_fee = 5.00

    weight_surcharge = weight * 1.50
    total_shipping = base_fee + weight_surcharge
    return total_shipping  # Handing the calculated answer back

# 2. Defining another function that wraps everything together
def generate_invoice(item_name, price, item_weight, destination):
    shipping_cost = calculate_shipping(item_weight, destination)
    tax_cost = price * COMPANY_TAX_RATE  # Using our global variable safely
    grand_total = price + shipping_cost + tax_cost

    print("\n--- OFFICIAL INVOICE ---")
    print(f"Product    : {item_name}")
    print(f"Item Price : ${price:.2f}")
    print(f"Shipping   : ${shipping_cost:.2f}")
    print(f"Tax Amount : ${tax_cost:.2f}")
    print(f"Grand Total: ${grand_total:.2f}")
    print("------------------------")

# 3. Calling our main function with real arguments
generate_invoice("Mechanical Keyboard", 120.00, 3.5, "international")
generate_invoice("Coffee Mug", 15.00, 0.8, "domestic")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Output:&lt;/em&gt; &lt;/p&gt;

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

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modularity&lt;/strong&gt;: Instead of writing complex shipping math twice, we isolated it in calculate_shipping(). The invoice function simply "calls" it to get the answer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scope Protection&lt;/strong&gt;: The base_fee calculation remains contained inside the shipping loop, keeping the rest of the application clean and conflict-free.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt;: By passing different arguments ("international" vs "domestic"), the identical logic yields customized invoices automatically.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Functions turn your code from long, disorganized scrolls of instructions into crisp, manageable toolboxes. By structuring your applications around defined blocks, parameters, and clean scope rules, you can scale your projects effortlessly without drowning in repetitive code blocks.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>beginners</category>
      <category>learning</category>
    </item>
    <item>
      <title>Python loops</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Thu, 22 Oct 2026 13:59:18 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/python-loops-1j53</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/python-loops-1j53</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine having to manually type out a thousand welcome emails or review a million lines of financial transactions one by one. It would be exhausting. Computers excel at doing repetitive tasks without getting tired, and in Python, we use loops to unlock this automation. Loops tell your program to run a specific block of code over and over again instantly, transforming manual data entry into a single click.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The Two Types of Loops
&lt;/h2&gt;

&lt;p&gt;Python gives us two primary ways to repeat code, depending on whether we know how many times we need to loop beforehand.&lt;/p&gt;

&lt;h3&gt;
  
  
  The for Loop
&lt;/h3&gt;

&lt;p&gt;You use a &lt;code&gt;for&lt;/code&gt; loop when you have a definite starting and ending point, like a list of items or a specific count. It goes through a collection one item at a time until it reaches the end.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet:&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;# Looping through a pre-made list
fruits = ["Apple", "Banana", "Cherry"]
for fruit in fruits:
    print(f"Processing: {fruit}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

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

&lt;h3&gt;
  
  
  The while Loop
&lt;/h3&gt;

&lt;p&gt;You use a &lt;code&gt;while&lt;/code&gt; loop when you don’t know exactly how many times you will need to repeat, but you know you want to keep going &lt;strong&gt;while&lt;/strong&gt; a certain condition remains &lt;code&gt;True&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Warning&lt;/em&gt;: You must make sure the condition eventually becomes &lt;code&gt;False&lt;/code&gt;, or your program will get stuck in an "infinite loop" and freeze!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet:&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;countdown = 3
while countdown &amp;gt; 0:
    print(countdown)
    countdown = countdown - 1  # Updates the condition
print("Blast off!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;&lt;/p&gt;

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

&lt;h2&gt;
  
  
  2. Upgrading Your Loops
&lt;/h2&gt;

&lt;p&gt;Sometimes you need finer control over how a loop behaves while it is running. Python provides built-in tools to change a loop's path or count its steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  break and continue (The Steering Wheel)
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;break&lt;/code&gt;:  This completely stops the loop immediately and jumps out of it, even if the loop wasn't finished. It is perfect for stopping a search early once you find what you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet:&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;while True:
    name = input('Enter your name (or type quit): ')

    if name == 'quit':
        break

print(f'Hello, {name}')

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Output&lt;/strong&gt;: This loop will still run until you type the input &lt;code&gt;quit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;continue&lt;/code&gt;: This skips the rest of the current turn and jumps straight to the start of the next turn. It is useful for skipping over bad or unneeded data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet:&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;for number in:
    if number == 3:
        continue  # Skip 3
    print(number)  #Output ; 1,2,3,4,5 #3 is skipped
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;h3&gt;
  
  
  Difference between &lt;code&gt;break&lt;/code&gt; and &lt;code&gt;continue&lt;/code&gt;
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;&lt;code&gt;break&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;continue&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Definition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Immediately terminates the entire loop.&lt;/td&gt;
&lt;td&gt;Skips the current iteration and moves to the next iteration.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stop a loop completely when a condition is met.&lt;/td&gt;
&lt;td&gt;Skip a particular item without stopping the loop.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Effect on loop&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Exits the loop immediately.&lt;/td&gt;
&lt;td&gt;Keeps the loop running.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Next iteration&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Does not execute.&lt;/td&gt;
&lt;td&gt;Executes if another iteration is available.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Execution afterward&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Continues with the first statement after the loop.&lt;/td&gt;
&lt;td&gt;Returns to the loop to process the next iteration.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Common use case&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stop searching when an item is found or a critical condition occurs.&lt;/td&gt;
&lt;td&gt;Skip invalid, unwanted, or irrelevant data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Example condition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;if badge == "STOLEN_BADGE": break&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;if "Guest" in badge: continue&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Effect in the badge example&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Stops processing at Entry #4 when a stolen badge is detected.&lt;/td&gt;
&lt;td&gt;Skips normal employee logging for Entry #2 (&lt;code&gt;Guest_Pass&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Employee_Jordan (Entry #5)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Not processed after &lt;code&gt;break&lt;/code&gt; at Entry #4.&lt;/td&gt;
&lt;td&gt;Would be processed if the stolen badge condition used &lt;code&gt;continue&lt;/code&gt; instead.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Works with&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Both &lt;code&gt;for&lt;/code&gt; and &lt;code&gt;while&lt;/code&gt; loops.&lt;/td&gt;
&lt;td&gt;Both &lt;code&gt;for&lt;/code&gt; and &lt;code&gt;while&lt;/code&gt; loops.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  enumerate() (The Step Counter)
&lt;/h3&gt;

&lt;p&gt;Normally, a for loop only gives you the item itself. If you also need to know the tracking number or position (index) of that item, you wrap your list inside &lt;code&gt;enumerate()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: Python starts counting positions at 0 instead of 1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet:&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;tasks = ["Email client", "Update spreadsheet", "Call manager"]
for index, task in enumerate(tasks):
    print(f"Task #{index + 1}: {task}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;h3&gt;
  
  
  3. Practical Example: The Automated Security Badge Scanner
&lt;/h3&gt;

&lt;p&gt;Let's bring all of these concepts together. This program simulates an office security checkpoint. It loops through arriving employees, tracks their entry order, handles guest badges, and completely shuts down if a security threat is detected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code snippet:&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;# --- AUTOMATED CHECKPOINT SCANNER ---

# A list representing badges scanned at the door in order
scanned_badges = ["Employee_Alex", "Guest_Pass", "Employee_Sam", "STOLEN_BADGE", "Employee_Jordan"]

print("--- STARTING DAILY SECURITY LOG ---")

# Using enumerate() to track the entry number alongside the badge name
for entry_number, badge in enumerate(scanned_badges):

    # 1. Using 'break' to instantly halt everything for a severe threat
    if badge == "STOLEN_BADGE":
        print(f"\nCRITICAL WARNING at Entry #{entry_number + 1}!")
        print("Stolen badge detected. Locking down all exit doors immediately.")
        break  # The loop stops dead in its tracks here

    # 2. Using 'continue' to skip standard employee logs for guest routing
    if "Guest" in badge:
        print(f"Entry #{entry_number + 1}: Guest badge detected. Rerouting to front desk...")
        continue  # Skips the normal logging step below and moves to the next badge

    # 3. Normal loop execution for regular employees
    print(f"Entry #{entry_number + 1}: {badge} verified. Access granted.")

print("\n--- SECURITY CHECKPOINT SYSTEM PAUSED ---")

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;for&lt;/code&gt;Loop&lt;/strong&gt;: It automatically moves from the first badge to the last badge without needing manual navigation.
-&lt;strong&gt;&lt;code&gt;enumerate()&lt;/code&gt;&lt;/strong&gt;: It gives us entry_number, allowing us to print clean logs like "Entry #1" and "Entry #2" dynamically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;break&lt;/code&gt;&lt;/strong&gt;: When it hits the security threat, it completely prevents the rest of the queue (Employee_Jordan) from being evaluated.
-** &lt;code&gt;continue&lt;/code&gt;**: When it hits the guest pass, it handles the visitor routing but skips printing the "Access granted" line meant only for employees.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Loops are the heavy lifters of programming. By combining &lt;code&gt;for&lt;/code&gt; and &lt;code&gt;while&lt;/code&gt; loops with steering tools like &lt;code&gt;break&lt;/code&gt;, &lt;code&gt;continue&lt;/code&gt;, and &lt;code&gt;enumerate()&lt;/code&gt;, you can instantly process massive collections of data with minimal code. You have evolved from writing single-file instructions to building powerful, automated pipelines.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>learning</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Operators and Conditionals</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Wed, 21 Oct 2026 19:01:02 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/operators-and-conditionals-54i1</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/operators-and-conditionals-54i1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In Python, operators and conditionals are the brain. They allow your code to do math, compare facts, and make independent choices. Instead of just running straight from top to bottom, your program gains the power to adapt dynamically based on the information it receives.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Operators
&lt;/h2&gt;

&lt;p&gt;We can simply ay that operators are &lt;code&gt;tools of logic&lt;/code&gt;.&lt;br&gt;
Operators are symbols that tell Python to perform specific actions on your data. They fall into three primary groups:&lt;/p&gt;
&lt;h3&gt;
  
  
  Arithmetic Operators
&lt;/h3&gt;

&lt;p&gt;These are your standard math symbols. They let you perform calculations instantly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; (Addition)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-&lt;/code&gt; (Subtraction)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; (Multiplcation)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/&lt;/code&gt; (Division)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code Snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;sum_of_x_and_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="n"&gt;subtraction_of_x_and_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="n"&gt;division_of_x_and_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;span class="n"&gt;multiplication_of_x_and_y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comparison Operators
&lt;/h3&gt;

&lt;p&gt;These symbols compare two values and always answer with a Boolean (&lt;code&gt;True&lt;/code&gt; or &lt;code&gt;False)&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;gt; (Greater than) &lt;/li&gt;
&lt;li&gt;&amp;lt; (Less than)&lt;/li&gt;
&lt;li&gt;== (Equal to Note: Python uses two equals signs to compare things, since a single equals sign is already used to assign variables!)&lt;/li&gt;
&lt;li&gt;!= (Not equal to)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Comparison operators
&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;
&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;#True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;#False
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt;&lt;span class="o"&gt;!=&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;#True
&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;#True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;    &lt;span class="c1"&gt;#False
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;#True
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;=&lt;/span&gt;&lt;span class="mi"&gt;74&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;#FAlse
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Logical Operators
&lt;/h3&gt;

&lt;p&gt;These let you combine multiple comparisons together to check for complex conditions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;and&lt;/code&gt;:Returns &lt;code&gt;True&lt;/code&gt; only if &lt;strong&gt;all&lt;/strong&gt; pieces are true (e.g., You can log in if your username &lt;strong&gt;and&lt;/strong&gt; password are correct).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;or&lt;/code&gt;: Returns &lt;code&gt;True&lt;/code&gt; if &lt;strong&gt;at least one&lt;/strong&gt; piece is true (e.g., You get a discount if it is Tuesday &lt;strong&gt;or&lt;/strong&gt; if you have a coupon).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;not&lt;/code&gt;: Flips the answer completely (turns &lt;code&gt;True&lt;/code&gt; to &lt;code&gt;False&lt;/code&gt;, and vice versa).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Making Choices: If, Elif, and Else
&lt;/h2&gt;

&lt;p&gt;Conditionals act like a digital crossroads in your code. They tell Python: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If this condition is true, run this specific block of code. Otherwise, look at the next option."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Python handles these paths using three simple structural keywords:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;if&lt;/strong&gt;: The initial starting point. If the statement after it is true, Python runs the indented code directly below it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;elif&lt;/strong&gt; (Short for "Else If"): The backup check. You can use as many &lt;code&gt;elif&lt;/code&gt; statements as you want to inspect alternative scenarios if the first &lt;code&gt;if&lt;/code&gt; fails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;else&lt;/strong&gt;: The safety net. It catches everything else if none of the previous conditions were met. It does not require any test condition.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# if / elif/ else(many paths)
&lt;/span&gt;
&lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Enter score: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Grade A - Excellent&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Grade B - Good&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Grace C - Average&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;score&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Grade D - Below average&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Grade F - Fail&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#Note: Python stops at the fist True condition . The order matters
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Remember our syntax rule&lt;/em&gt;: The code inside each path must be cleanly indented so Python knows exactly which instruction goes with which choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Practical Example: The Automated Smart Thermostat
&lt;/h2&gt;

&lt;p&gt;Let's combine all of these operators and conditions into a practical program that mimics a modern smart home system. It checks the current indoor temperature and the home's occupancy status to decide how to manage the HVAC unit.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# --- SMART THERMOSTAT CONTROLLER ---
&lt;/span&gt;
&lt;span class="c1"&gt;# 1. Gathering Environmental Data
&lt;/span&gt;&lt;span class="n"&gt;current_temp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter current room temperature (°F): &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;is_home_empty_input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Is the house currently empty? (yes/no): &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Convert text input into a true/false Boolean state
&lt;/span&gt;&lt;span class="n"&gt;is_home_empty&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;is_home_empty_input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;yes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Evaluating Conditions Using Operators &amp;amp; Conditionals
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;--- SYSTEM STATUS REPORT ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Rule 1: Energy saving mode if no one is home
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;is_home_empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Status: Eco-Mode Active (House Empty). System powered down.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Rule 2: It's crowded/occupied AND too hot
&lt;/span&gt;&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;current_temp&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;75&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;is_home_empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Status: Room is too hot. Turning on the Air Conditioning.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Rule 3: It's crowded/occupied AND too cold
&lt;/span&gt;&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;current_temp&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;is_home_empty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Status: Room is too cold. Turning on the Central Heating.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Rule 4: Temperature is perfectly fine
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Status: Temperature is optimal. System idling.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;----------------------------&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Arithmetic &amp;amp; Comparisons:&lt;/strong&gt; It evaluates &lt;code&gt;current_temp &amp;gt;= 75&lt;/code&gt; and matches strings to set &lt;code&gt;is_home_empty&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Logical Operators:&lt;/strong&gt; It uses &lt;code&gt;and not&lt;/code&gt; to ensure the system only runs heaters or coolers when people are actively in the building.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Conditionals:&lt;/strong&gt; The &lt;code&gt;if-elif-else&lt;/code&gt; structure prevents the system from conflicting with itself, selecting exactly one correct mode of operation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;By mastering operators and conditionals, your Python code transitions from a basic calculator to an active decision-maker. You can now write programs that analyze dynamic data, filter user parameters, and adapt on the fly.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>beginners</category>
      <category>learning</category>
    </item>
    <item>
      <title>Python Basics</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Wed, 21 Oct 2026 17:56:04 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/python-basics-43e6</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/python-basics-43e6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Data is the new oil, but Python is the combustion engine.&lt;/strong&gt; While traditional enterprise tools crash under the weight of modern datasets, Python enables leaders and future professionals to scale operations through automation, predictive analytics, and custom machine learning pipelines. &lt;br&gt;
It is no longer just a programming language, it is the core infrastructure powering algorithmic decision-making in the modern economy.&lt;/p&gt;

&lt;p&gt;In this article, we will cover the basics of Python.&lt;br&gt;
This includes;&lt;br&gt;
            - Variables&lt;br&gt;
            - Data Types&lt;br&gt;
            - Input &amp;amp; Output&lt;br&gt;
            - Basic Python syntax&lt;br&gt;
            - Practical Example&lt;/p&gt;
&lt;h2&gt;
  
  
  Variables (The Digital Storage Units)
&lt;/h2&gt;

&lt;p&gt;Think of variables as labeled storage tags for data. When you write programs, you constantly need to save information. For example a price, a username, or a calculation result. Variables give you a way to name that information so you can easily find and use it later.&lt;br&gt;
In Python, creating a variable is incredibly straightforward. You simply write the name you want to use, followed by an equals sign (=), and then the data you want to save.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;19.09&lt;/span&gt; 
&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gideon Kiprono&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;While it is easy to think of a variable as a box holding your data, Python actually treats them like &lt;strong&gt;sticky notes.&lt;/strong&gt;&lt;br&gt;
When you write,&lt;br&gt;
&lt;code&gt;price = 19.99&lt;/code&gt;,&lt;br&gt;
Python creates the number 19.99 in the computer's memory, and then sticks the label price onto it. If you decide to change that value later, for example, &lt;br&gt;
&lt;code&gt;price = 24.99&lt;/code&gt;,&lt;br&gt;
Python doesn't erase the old number. It simply moves the price label to the new number.&lt;/p&gt;
&lt;h3&gt;
  
  
  Dynamic Typing
&lt;/h3&gt;

&lt;p&gt;In many other programming languages, you have to tell the computer exactly what kind of data a variable will hold before you can even use it. You have to explicitly state, "This variable will only hold whole numbers," or "This variable will only hold text."&lt;br&gt;
Python is much smarter. It uses a concept called &lt;strong&gt;dynamic typing&lt;/strong&gt;. This means Python looks at the data you provide and figures out what type of information it is automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;19.09&lt;/span&gt; &lt;span class="c1"&gt;#Python automatically knows this is a float number
&lt;/span&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Gideon Kiprono&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="c1"&gt;#string
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This flexibility makes writing code much faster and heavily reduces the amount of setup code you have to type. You can focus purely on solving the problem at hand, rather than managing structural rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data types (The Building Blocks of Information)
&lt;/h2&gt;

&lt;p&gt;Just like we use different tools for different tasks, Python organizes information into different categories called data types. Because Python needs to know how to handle your data, like adding numbers together or combining pieces of text, it assigns a specific type to every piece of information you create.&lt;br&gt;
Here are the four most common data types you will use every day:&lt;/p&gt;
&lt;h3&gt;
  
  
  Text (Strings)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;A string&lt;/strong&gt; is simply any text data wrapped in quotation marks. It can be a single letter, a full sentence, or even a password. The quotes tell Python to treat the contents as literal text rather than code instructions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;welcome_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Welcome to Python!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Whole Numbers (Integers)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;An integer&lt;/strong&gt; is any whole number without a decimal point. These can be positive or negative. You use integers whenever you need to count distinct items, like items in a shopping cart or website visits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Decimals (Floats)
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;floating-point number&lt;/strong&gt; (or float) is a number that includes a decimal point. You use floats whenever you need precision, such as dealing with money, percentages, or GPS coordinates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;tax_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  True/False States (Booleans)
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;boolean&lt;/strong&gt; represents binary logic and can only have one of two values: &lt;em&gt;True&lt;/em&gt; or &lt;em&gt;False&lt;/em&gt;. (Note the capital letters!). These act like digital light switches and are vital for helping your program make decisions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;is_logged_in&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Input and Output (Talking to Your Program )
&lt;/h2&gt;

&lt;p&gt;A program becomes truly useful when it can interact with the outside world. It needs a way to &lt;strong&gt;take in information&lt;/strong&gt; from a user (Input) and a way to &lt;strong&gt;display results&lt;/strong&gt; back to them (Output). Python makes this exchange incredibly easy using two built-in commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Output: Showing Results with &lt;code&gt;print()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To display text or variables on the screen, you use the &lt;code&gt;print()&lt;/code&gt; function. It is the tool your program uses to speak to the screen.&lt;/p&gt;

&lt;p&gt;Modern Python uses a feature called &lt;strong&gt;f-strings (formatted strings)&lt;/strong&gt; to easily mix text and variables together. You simply put an &lt;code&gt;f&lt;/code&gt; outside the quotation marks and place your variables inside curly braces &lt;code&gt;{}&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alex&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Displays: Hello, Alex!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Input: Gathering Data with &lt;code&gt;input()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To ask a user for information, you use the &lt;code&gt;input()&lt;/code&gt; function. This command pauses your program and waits for the user to type something and press &lt;code&gt;Enter&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;favorite_color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;What is your favorite color? &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Cool! I like &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;favorite_color&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; too.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Python always captures user input as &lt;code&gt;text (a string)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you ask a user for a number to do math with, Python will treat that number like text letters. To fix this, you must wrap the input inside a conversion command like &lt;code&gt;int() (for whole numbers)&lt;/code&gt; or &lt;code&gt;float() (for decimals)&lt;/code&gt;. This process is called &lt;strong&gt;type casting.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Converting text input into a whole number so we can do math
&lt;/span&gt;&lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter your age: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;next_year&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;age&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Next year you will be &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;next_year&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; years old.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic Python Syntax
&lt;/h2&gt;

&lt;p&gt;Every language has grammar rules, and programming languages are no different. The rules that govern how you write code are called syntax. Python is famous for having one of the cleanest, most minimalist syntax designs in the world, making it look almost like plain English.&lt;br&gt;
Here are the basic rules you need to know to write valid Python code:&lt;/p&gt;
&lt;h3&gt;
  
  
  The Power of Whitespace (&lt;code&gt;Indentation&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;In many programming languages, you have to use messy curly braces {} or keywords like END to show where a block of code begins and finishes. Python simplifies this by using &lt;strong&gt;spaces or tabs (called indentation)&lt;/strong&gt;.&lt;br&gt;
By indenting your code, you visually show Python which lines belong together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user_is_happy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Keep doing what you&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;re doing!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# Indented line belongs to the 'if' statement
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Keeping your spacing consistent is vital. If your lines do not align correctly, Python will pause and show an &lt;code&gt;IndentationError&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Case Sensitivity Matters
&lt;/h3&gt;

&lt;p&gt;Python reads code very literally and pays close attention to capitalization. To Python, a lowercase letter and an uppercase letter are entirely different.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Alex&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;Username&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sam&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;  &lt;span class="c1"&gt;# Python treats this as a completely separate variable!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comments
&lt;/h3&gt;

&lt;p&gt;Sometimes you want to leave notes inside your code to explain how a certain part works. You can do this by using the hashtag symbol (#). Anything you type after a # is completely ignored by the computer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# This is a comment. Python will skip this line entirely.
&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;10.00&lt;/span&gt;  &lt;span class="c1"&gt;# You can also add comments at the end of a line
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Practical example
&lt;/h2&gt;

&lt;p&gt;Now that we have covered variables, data types, inputs, outputs, and basic syntax, let’s bring them all together into a real, working program.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Digital Receipt Calculator
&lt;/h3&gt;

&lt;p&gt;This simple script acts as a receipt calculator. It asks for a product's price, calculates the sales tax, determines the grand total, and prints a clean summary for the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# --- DIGITAL RECEIPT CALCULATOR ---
&lt;/span&gt;
&lt;span class="c1"&gt;# 1. Inputs &amp;amp; Data Types
# We ask the user for data. We convert the price to a float (decimal) 
# and the quantity to an int (whole number) so we can do math.
&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter the item name: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;float&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter the item price: $&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter the quantity purchased: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;# 2. Variables &amp;amp; Basic Math
# We create variables to calculate and store the totals.
&lt;/span&gt;&lt;span class="n"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;
&lt;span class="n"&gt;tax_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.08&lt;/span&gt;  &lt;span class="c1"&gt;# Representing an 8% sales tax
&lt;/span&gt;&lt;span class="n"&gt;calculated_tax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;
&lt;span class="n"&gt;grand_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;subtotal&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;calculated_tax&lt;/span&gt;

&lt;span class="c1"&gt;# 3. Basic Python Syntax (Decision Making)
# We use an 'if' statement with indentations to check for a discount.
&lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;grand_total&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mf"&gt;100.00&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;discount_applied&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="n"&gt;grand_total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;grand_total&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;0.90&lt;/span&gt;  &lt;span class="c1"&gt;# Apply a 10% discount
&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;discount_applied&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;

&lt;span class="c1"&gt;# 4. Output
# We use f-strings to display a cleanly formatted receipt back to the user.
&lt;/span&gt;&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;--- FINAL RECEIPT ---&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Item: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Subtotal: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;subtotal&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Tax (8%): $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;calculated_tax&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;discount_applied&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;A 10% discount was applied to your order!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Grand Total: $&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;grand_total&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;---------------------&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Variables&lt;/code&gt;: product_name, price, and grand_total hold our information as it moves through the program.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Data Types&lt;/code&gt;: We mix strings (text names), floats (prices and taxes), integers (quantities), and booleans (True/False for the discount status).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Input/Output&lt;/code&gt;: input() captures what the user typed, and print() cleanly formats and shares the mathematical results.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Basic Syntax&lt;/code&gt;: We use hashtags for comments to explain the code, capital letters for True and False, and strict indentation under the if and else lines to control exactly when the discount rules should trigger.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Writing your first lines of Python code is more than just an academic exercise, it is the moment you stop merely consuming technology and start creating it. By understanding how to manipulate variables, manage data types, handle inputs, and structure clean syntax, you have unlocked the foundational blueprint used by software engineers, data scientists, and creators worldwide.&lt;br&gt;
The beauty of Python lies in its scalability. The exact same basic logic you used to build a simple receipt calculator is what powers complex artificial intelligence models, massive data pipelines, and global web applications.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You now have the keys to the language. The best way to master it is to keep building, experimenting, and turning your everyday ideas into working code.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Happy programming!&lt;/p&gt;

</description>
      <category>python</category>
      <category>discuss</category>
      <category>learning</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>KIOSK_MANAGER : End to end python project</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Mon, 19 Oct 2026 16:38:51 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/kioskmanager-end-to-end-python-project-4n61</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/kioskmanager-end-to-end-python-project-4n61</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a write-up on how we built a real stock-and-sales system for a Nairobi kiosk using only the Python basics: variables, conditionals, loops, functions, data structures, strings and files&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;A small kiosk in Nairobi tracks everything in a notebook: how many loaves of bread are left, what was sold today, how much money came in. Notebooks get lost, pages get smudged, and adding up a day's sales by hand is slow and error-prone.&lt;/p&gt;

&lt;p&gt;Our group was asked to replace the notebook with a program. The owner needs to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;See what is in stock.&lt;/li&gt;
&lt;li&gt;Restock items or add new ones.&lt;/li&gt;
&lt;li&gt;Sell products and record each sale.&lt;/li&gt;
&lt;li&gt;See a sales report.&lt;/li&gt;
&lt;li&gt;Search for a product.&lt;/li&gt;
&lt;li&gt;Keep everything saved between days.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The twist is that we could only use what we had learned in six sessions of Python: no classes, no try/except, no csv module. That constraint makes it a great end-to-end project, because every basic skill has to earn its place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Scope
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Skill&lt;/th&gt;
&lt;th&gt;How it shows up in Kiosk Manager&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Basics&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;input()&lt;/code&gt; prompts, correct data types, f-string output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Conditionals&lt;/td&gt;
&lt;td&gt;Is there enough stock? Is the menu choice valid?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Loops&lt;/td&gt;
&lt;td&gt;A &lt;code&gt;while True&lt;/code&gt; menu; &lt;code&gt;for&lt;/code&gt; loops over sales and stock&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Functions&lt;/td&gt;
&lt;td&gt;Every feature is its own function, called from a clean &lt;code&gt;main()&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data structures&lt;/td&gt;
&lt;td&gt;Dictionary for stock, list of tuples for sales, set of unique items sold&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Strings and files&lt;/td&gt;
&lt;td&gt;Cleaning input with &lt;code&gt;.strip()&lt;/code&gt;, &lt;code&gt;.title()&lt;/code&gt;, &lt;code&gt;.lower()&lt;/code&gt;; saving and loading &lt;code&gt;.txt&lt;/code&gt; files&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 1: Design the data
&lt;/h3&gt;

&lt;p&gt;Before writing any code, we decided how the data would look. Good structure makes everything after it easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stock is a dictionary of dictionaries.&lt;/strong&gt; The product name is the key, and the value holds price and quantity:&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%2Fkdnfe8m0odm57izg0ncr.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkdnfe8m0odm57izg0ncr.JPG" alt="inventory initialization" width="442" height="127"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Looking up inventory["Pen"]["quantity"] is instant and readable, and checking whether a product exists is just name in inventory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sales are a list of tuples&lt;/strong&gt;. Each sale never changes after it happens, which is exactly what a tuple is for:&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%2Fq217y5p580g444d0oh2q.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fq217y5p580g444d0oh2q.JPG" alt="sales log" width="367" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Unique products sold are a set.&lt;/strong&gt; A set ignores duplicates, so adding "Pen" twice still counts it once:&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Step 2: Welcome and setup
&lt;/h3&gt;

&lt;p&gt;The program opens by asking for the kiosk's name and the owner's name. Raw &lt;strong&gt;input()&lt;/strong&gt; is never trusted: &lt;strong&gt;.strip()&lt;/strong&gt; removes stray spaces and &lt;strong&gt;.title()&lt;/strong&gt; fixes the capitalisation, so "  &lt;em&gt;&lt;strong&gt;navas herbert&lt;/strong&gt;&lt;/em&gt; " becomes &lt;strong&gt;&lt;em&gt;"Navas Herbert".&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We split this into two small functions. One collects the information and returns &lt;em&gt;&lt;strong&gt;two values&lt;/strong&gt;&lt;/em&gt;; the other prints the banner.&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%2Ftivp0bfn3i0emvkt3j28.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftivp0bfn3i0emvkt3j28.JPG" alt="welcome" width="799" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The file names sit at the top as constants. If we ever rename a file, we change it in one place.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Saving and loading data
&lt;/h3&gt;

&lt;p&gt;Data that vanishes when the program closes is useless to a shopkeeper, so we used plain text files with one comma-separated record per line. This is what &lt;em&gt;Dictionary.txt&lt;/em&gt; looks like:&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%2Ft2y7o9bu6e1tq0cw7apz.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft2y7o9bu6e1tq0cw7apz.JPG" alt="dictionary" width="740" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On startup, &lt;strong&gt;os.path.exists()&lt;/strong&gt; decides whether to load that file or begin with a small default inventory. Each line is turned back into a dictionary entry with &lt;strong&gt;.split(",")&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  to come back here!!!!
&lt;/h4&gt;

&lt;p&gt;Saving uses three small functions, and the file mode matters:&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%2Ft0qile0qq9m8cpeqyaqt.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft0qile0qq9m8cpeqyaqt.JPG" alt="saving" width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mode "w" overwrites&lt;/strong&gt;, which is right for inventory because the file should always hold today's stock.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Mode "a" appends&lt;/strong&gt;, which is right for sales because yesterday's sales must never be erased.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Viewing stock
&lt;/h3&gt;

&lt;p&gt;Aligned columns come from f-string padding: &lt;strong&gt;{product:&amp;lt;15}&lt;/strong&gt; left-aligns a value in a 15-character column.&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%2Fb0r95wmvga2fgqpbzhfv.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb0r95wmvga2fgqpbzhfv.JPG" alt="View stock" width="709" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Adding or restocking a product
&lt;/h3&gt;

&lt;p&gt;One function handles both jobs. If the product exists, we add units to it; if not, we ask for a price and a starting quantity. Every input is checked with &lt;strong&gt;.isdigit() before converting with int()&lt;/strong&gt;, so typing letters can never crash the program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ================function to add/ restock a product========================
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_or_restock_product&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;

    &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter product name: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Validate product name
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid product name. Please enter a valid product name.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="c1"&gt;# Product already exists
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter quantity to add: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quantity must be a number.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quantity must be greater than 0.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quantity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;

        &lt;span class="nf"&gt;save_inventory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; has been restocked successfully.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Brand-new product
&lt;/span&gt;    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

        &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter product price: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Enter product quantity: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Price and quantity must be numbers.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Price and quantity must be greater than 0.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quantity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nf"&gt;save_inventory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; has been added successfully.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repeated &lt;em&gt;return&lt;/em&gt; statements are _"guard clause_s": the moment something is wrong, the function stops. The successful path stays flat and easy to read.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Selling a product
&lt;/h3&gt;

&lt;p&gt;This is where the business logic lives. A sale only goes through if the product exists, the quantity is a positive whole number, and there is enough stock.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#=============== Function to Sell a Product================
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sell_product&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Which product to sell: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;title&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# Validate product name
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Invalid product name. Please enter a valid product name.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; is not available in the inventory.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Enter the units to be sold: &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Quantity must be a digit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Quantity should be greater than 0&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quantity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not enough stock. Only &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;quantity&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; units available.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;

        &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;

        &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;quantity&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-=&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;

        &lt;span class="n"&gt;sale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;sales_log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sale&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;sold_products&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;save_inventory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;save_sales_log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;save_sold_products&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sold &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; units of &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; sucessfuly for &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Sale successful.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Product: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Quantity: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Total: KES &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nothing changes until every check has passed. That is why a refused sale never leaves the stock half-updated.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: The sales report
&lt;/h3&gt;

&lt;p&gt;One loop does three jobs: &lt;br&gt;
       - it prints each sale, &lt;br&gt;
       - adds to a revenue &lt;em&gt;accumulator&lt;/em&gt;, &lt;br&gt;
       - builds a dictionary of units sold per product. &lt;br&gt;
After the loop, &lt;strong&gt;max()&lt;/strong&gt; picks the best seller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;#===============Function to print the sales report==============================
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;sales_report&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;sales_log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No sales yet this session.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;SALES REPORT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Product&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Quantity&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Total (KES)&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;revenue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;units_by_product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;sales_log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="si"&gt;}{&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;revenue&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
        &lt;span class="n"&gt;units_by_product&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;units_by_product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;

    &lt;span class="n"&gt;best&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;units_by_product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;units_by_product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Total revenue: KES &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;revenue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unique products sold: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sold_products&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Best seller: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;units_by_product&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;best&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; units)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;.get(product, 0)&lt;/strong&gt; returns 0 the first time a product appears, which avoids a missing-key error. We define "best seller" as most units sold, and stay consistent with that.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8: Searching products
&lt;/h3&gt;

&lt;p&gt;A forgiving search lowercases both the search term and the product name, then uses the in operator, so typing calc finds Calculator.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ===============Function to search products====================
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_products&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Search for a product: &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Please type something to search for.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;

    &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;details&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;inventory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;term&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;KES &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;price&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;Qty: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;details&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;quantity&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No matches found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;em&gt;found&lt;/em&gt; flag is a classic pattern: assume nothing matched, flip it to &lt;em&gt;True&lt;/em&gt; on the first match, and print "No matches found" only if it never flipped.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 9: The main program
&lt;/h3&gt;

&lt;p&gt;Because every feature is its own function, the main flow reads almost like plain English: ask, welcome, load, then loop until the user exits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;kiosk_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;owner_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;ask_kiosk_info&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;show_owner_details&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kiosk_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;owner_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="n"&gt;inventory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_inventory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;sales_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;sold_products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;==============MAIN MENU============== &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1. View Stock&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2. Add/ Restock a Product&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3. Sell a Product&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;4. View Sales Report&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;5. Search Products&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;6. Exit&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Enter your choice (Between 1 and 6): &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;strip&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isdigit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Invalid choice. Please enter a number between 1 and 6&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;
    &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;choice&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Invalid choice. Please enter a number between 1 and 6&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;continue&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;view_inventory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;add_or_restock_product&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;sell_product&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;sales_report&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="n"&gt;choice&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;search_products&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;else&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;save_inventory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;save_sales_log&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;save_sold_products&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Exiting. Goodbye, &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;owner_name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;!&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The menu choice is validated in two steps: &lt;strong&gt;.isdigit()&lt;/strong&gt; first (is it a number at all?), then a range check (is it 1 to 6?). &lt;strong&gt;continue&lt;/strong&gt; sends the loop straight back to the menu instead of crashing.&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%2Fhyw8scm2eel6owrc8n8y.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyw8scm2eel6owrc8n8y.JPG" alt="Output 1" width="449" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

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

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

&lt;p&gt;Kiosk Manager is small, but it is a complete program: it takes input, applies business rules, stores data, reports results and survives a restart. That is the full loop of real software, and if every group member can explain every function above, we built something a real shopkeeper could use tomorrow morning.&lt;/p&gt;

</description>
      <category>python</category>
      <category>beginners</category>
      <category>learning</category>
      <category>coding</category>
    </item>
    <item>
      <title>Understanding Subqueries and CTE's</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Sat, 26 Sep 2026 10:02:34 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/understanding-subqueries-and-ctes-120m</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/understanding-subqueries-and-ctes-120m</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine you are a data analyst working for a retail company. Your manager asks you to identify customers who spend more than the average customer, employees earning above their department's average salary, or products generating the highest revenue.&lt;/p&gt;

&lt;p&gt;You already know how to retrieve data using SELECT, filter records using WHERE, and combine tables using JOIN. However, some business questions require you to perform multiple calculations before arriving at the final answer.&lt;/p&gt;

&lt;p&gt;For example, how would you identify employees earning above the company's average salary without knowing the average salary beforehand?&lt;/p&gt;

&lt;p&gt;You would first need to calculate the average salary and then use that result to identify employees whose salaries exceed it.&lt;/p&gt;

&lt;p&gt;This is where SQL Subqueries and Common Table Expressions (CTEs) come in.&lt;/p&gt;

&lt;p&gt;Both techniques allow you to break down complex analytical problems into smaller, more manageable queries. They help you perform intermediate calculations, filter records based on the results of other queries, and organize your SQL code more effectively.&lt;/p&gt;

&lt;p&gt;In this article, we will explore what subqueries and CTEs are, how they work, their key differences, and how to apply them to real-world data analysis problems.&lt;/p&gt;

&lt;h2&gt;
  
  
  SQL Subqueries
&lt;/h2&gt;

&lt;p&gt;A subquery, also known as a nested query or inner query, is a SQL query written inside another SQL query.&lt;/p&gt;

&lt;p&gt;The inner query produces a result that the outer query uses to perform another operation.&lt;/p&gt;

&lt;p&gt;In simple terms, a subquery allows you to answer one question and use that answer to solve another question within the same SQL statement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Basic Syntax of a Subquery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;SELECT column_name&lt;br&gt;
FROM table_name&lt;br&gt;
WHERE column_name operator (&lt;br&gt;
    SELECT column_name&lt;br&gt;
    FROM table_name&lt;br&gt;
);&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The query inside the parentheses is called the inner query or subquery, while the query surrounding it is called the outer query.&lt;/p&gt;

&lt;p&gt;For a simple, independent subquery, SQL can evaluate the inner query and use its result in the outer query. However, the actual execution strategy depends on the database engine and the type of subquery.&lt;/p&gt;

&lt;p&gt;Let's understand this concept using a practical example.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example 1: Finding Employees Earning Above the Average Salary
&lt;/h3&gt;

&lt;p&gt;Suppose we have an employees table containing the following information:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tbody&gt;
&lt;tr&gt;
    &lt;th&gt;employee_id&lt;/th&gt;
    &lt;th&gt;employee_name&lt;/th&gt;
    &lt;th&gt;department&lt;/th&gt;
    &lt;th&gt;salary&lt;/th&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td&gt;1&lt;/td&gt;
    &lt;td&gt;John&lt;/td&gt;
    &lt;td&gt;IT&lt;/td&gt;
    &lt;td&gt;80000&lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td&gt;2&lt;/td&gt;
    &lt;td&gt;Mary&lt;/td&gt;
    &lt;td&gt;HR&lt;/td&gt;
    &lt;td&gt;55000&lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td&gt;3&lt;/td&gt;
    &lt;td&gt;Peter&lt;/td&gt;
    &lt;td&gt;IT&lt;/td&gt;
    &lt;td&gt;70000&lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td&gt;4&lt;/td&gt;
    &lt;td&gt;Jane&lt;/td&gt;
    &lt;td&gt;Finance&lt;/td&gt;
    &lt;td&gt;45000&lt;/td&gt;
  &lt;/tr&gt;

  &lt;tr&gt;
    &lt;td&gt;5&lt;/td&gt;
    &lt;td&gt;David&lt;/td&gt;
    &lt;td&gt;Finance&lt;/td&gt;
    &lt;td&gt;50000&lt;/td&gt;
  &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The HR manager wants to identify employees earning above the company's average salary.&lt;/p&gt;

&lt;p&gt;To solve this problem, we need to calculate the average salary and then compare each employee's salary against that average.&lt;/p&gt;
&lt;h5&gt;
  
  
  Step 1: Calculate the average salary.
&lt;/h5&gt;

&lt;p&gt;&lt;strong&gt;SELECT AVG(salary) AS average_salary&lt;br&gt;
FROM employees;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The AVG() function calculates the average salary across all employees.&lt;/p&gt;

&lt;p&gt;The result is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;average_salary: 60000&lt;/strong&gt;&lt;/p&gt;
&lt;h5&gt;
  
  
  Step 2: Use the average salary to identify employees earning above it.
&lt;/h5&gt;

&lt;p&gt;Instead of manually entering 60000 into another query, we can combine both operations using a subquery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SELECT&lt;br&gt;
    employee_name,&lt;br&gt;
    department,&lt;br&gt;
    salary&lt;br&gt;
FROM employees&lt;br&gt;
WHERE salary &amp;gt; (&lt;br&gt;
    SELECT AVG(salary)&lt;br&gt;
    FROM employees&lt;br&gt;
);&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How does this query work?&lt;/p&gt;

&lt;p&gt;The inner query:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SELECT AVG(salary)&lt;br&gt;
FROM employees;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;calculates the company's average salary.&lt;/p&gt;

&lt;p&gt;The outer query:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SELECT&lt;br&gt;
    employee_name,&lt;br&gt;
    department,&lt;br&gt;
    salary&lt;br&gt;
FROM employees&lt;br&gt;
WHERE salary &amp;gt; (...);&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;retrieves employees whose salaries exceed the value returned by the inner query.&lt;/p&gt;

&lt;p&gt;The final result is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;employee_name&lt;/th&gt;
&lt;th&gt;department&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;/tr&gt;


&lt;tr&gt;
    &lt;td&gt;John&lt;/td&gt;
    &lt;td&gt;IT&lt;/td&gt;
    &lt;td&gt;80000&lt;/td&gt;
  &lt;/tr&gt;

&lt;tr&gt;
    &lt;td&gt;Peter&lt;/td&gt;
    &lt;td&gt;IT&lt;/td&gt;
    &lt;td&gt;70000&lt;/td&gt;
  &lt;/tr&gt;

&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice that we did not need to enter the average salary manually. The query calculates it directly from the data.&lt;/p&gt;

&lt;p&gt;If the employee salaries change, running the query again will use the updated average salary.&lt;/p&gt;

&lt;p&gt;This makes subqueries particularly useful when working with dynamic data.&lt;/p&gt;
&lt;h3&gt;
  
  
  Types of SQL Subqueries
&lt;/h3&gt;

&lt;p&gt;Subqueries can be classified according to the number of values they return and how they interact with the outer query.&lt;/p&gt;
&lt;h4&gt;
  
  
  1. Scalar Subqueries
&lt;/h4&gt;

&lt;p&gt;A scalar subquery returns a single value, such as an average salary, maximum price, or total revenue.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SELECT&lt;br&gt;
    employee_name,&lt;br&gt;
    salary&lt;br&gt;
FROM employees&lt;br&gt;
WHERE salary &amp;gt; (&lt;br&gt;
    SELECT AVG(salary)&lt;br&gt;
    FROM employees&lt;br&gt;
);&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here, the subquery returns one value: the average salary.&lt;/p&gt;

&lt;p&gt;The outer query uses that value to filter employees.&lt;/p&gt;
&lt;h4&gt;
  
  
  2. Multiple-Row Subqueries
&lt;/h4&gt;

&lt;p&gt;A multiple-row subquery returns more than one row.&lt;/p&gt;

&lt;p&gt;These subqueries are commonly used with operators such as IN, ANY, and ALL.&lt;/p&gt;

&lt;p&gt;For example, suppose we have a departments table containing department names and locations.&lt;/p&gt;

&lt;p&gt;We want to identify employees working in departments located in Nairobi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SELECT&lt;br&gt;
    employee_name,&lt;br&gt;
    department&lt;br&gt;
FROM employees&lt;br&gt;
WHERE department IN (&lt;br&gt;
    SELECT department_name&lt;br&gt;
    FROM departments&lt;br&gt;
    WHERE location = 'Nairobi'&lt;br&gt;
);&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The inner query retrieves the names of departments located in Nairobi.&lt;/p&gt;

&lt;p&gt;The outer query then selects employees whose department appears in that list.&lt;/p&gt;
&lt;h4&gt;
  
  
  3. Correlated Subqueries
&lt;/h4&gt;

&lt;p&gt;A correlated subquery is a subquery that references a column from the outer query.&lt;/p&gt;

&lt;p&gt;Unlike an independent subquery, it depends on values supplied by the outer query.&lt;/p&gt;

&lt;p&gt;For example, suppose we want to identify employees earning above the average salary in their respective departments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SELECT&lt;br&gt;
    e.employee_name,&lt;br&gt;
    e.department,&lt;br&gt;
    e.salary&lt;br&gt;
FROM employees AS e&lt;br&gt;
WHERE e.salary &amp;gt; (&lt;br&gt;
    SELECT AVG(e2.salary)&lt;br&gt;
    FROM employees AS e2&lt;br&gt;
    WHERE e2.department = e.department&lt;br&gt;
);&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this example, the subquery calculates the average salary for the department associated with each employee in the outer query.&lt;/p&gt;

&lt;p&gt;The condition:&lt;/p&gt;

&lt;p&gt;WHERE e2.department = e.department****&lt;/p&gt;

&lt;p&gt;connects the inner query to the outer query.&lt;/p&gt;

&lt;p&gt;This allows each employee's salary to be compared against the average salary of their own department rather than the company-wide average.&lt;/p&gt;

&lt;p&gt;Correlated subqueries are useful when performing comparisons within groups, such as comparing individual customer spending against the average spending of customers in the same region.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Common Table Expressions (CTEs)
&lt;/h2&gt;

&lt;p&gt;A Common Table Expression (CTE) is a temporary named result set defined within a SQL statement using the WITH keyword.&lt;/p&gt;

&lt;p&gt;A CTE allows you to write a query, give its result a meaningful name, and reference that result in the main SQL statement.&lt;/p&gt;

&lt;p&gt;Think of a CTE as creating a temporary working table that helps you organize a complex query into smaller, logical steps.&lt;/p&gt;

&lt;p&gt;Unlike a permanent database table, a CTE does not remain available for use by later, separate SQL statements.&lt;/p&gt;
&lt;h3&gt;
  
  
  Basic Syntax of a CTE
&lt;/h3&gt;

&lt;p&gt;The basic structure of a Common Table Expression looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;cte_name&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;column_name&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;table_name&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;condition&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;cte_name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break this down.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;WITH&lt;/code&gt; keyword tells SQL that we are defining a Common Table Expression.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cte_name&lt;/code&gt; is the name we give to the result produced by the query inside the parentheses.&lt;/p&gt;

&lt;p&gt;The main query can then reference the CTE using that name.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITH
    ↓
Create temporary result
    ↓
Give it a name
    ↓
Use that name in the main query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's apply this to our employee data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2: Finding Employees Earning Above the Average Salary Using a CTE
&lt;/h3&gt;

&lt;p&gt;Earlier, we solved this problem using a subquery:&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;employee_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;salary&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can solve the same problem using a CTE.&lt;/p&gt;

&lt;p&gt;First, we create a CTE that calculates the company's average salary.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;average_salary&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;avg_salary&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;employee_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;average_salary&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avg_salary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's understand what is happening.&lt;/p&gt;

&lt;p&gt;The CTE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;average_salary&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;avg_salary&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;calculates the average salary and gives the result the name &lt;code&gt;average_salary&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Conceptually, it produces:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;avg_salary&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;60000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The main query then uses that result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;employee_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;department&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;average_salary&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avg_salary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final result is:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;employee_name&lt;/th&gt;
&lt;th&gt;department&lt;/th&gt;
&lt;th&gt;salary&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;John&lt;/td&gt;
&lt;td&gt;IT&lt;/td&gt;
&lt;td&gt;80000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Peter&lt;/td&gt;
&lt;td&gt;IT&lt;/td&gt;
&lt;td&gt;70000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We have therefore answered the same question using two different approaches.&lt;/p&gt;

&lt;p&gt;The subquery places the average calculation directly inside the &lt;code&gt;WHERE&lt;/code&gt; condition, while the CTE calculates the average first, gives the result a meaningful name, and then references that result in the main query.&lt;/p&gt;

&lt;p&gt;For a simple problem like this, the subquery may be shorter. However, as queries become more complex, CTEs can make SQL code easier to read and maintain.&lt;/p&gt;




&lt;h3&gt;
  
  
  Using a CTE to Summarize Data
&lt;/h3&gt;

&lt;p&gt;CTEs become particularly useful when we need to perform an intermediate calculation before carrying out further analysis.&lt;/p&gt;

&lt;p&gt;Suppose we have a &lt;code&gt;sales&lt;/code&gt; table containing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;15000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;25000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;30000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;20000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Management wants to identify customers who have spent more than KSh 30,000 in total.&lt;/p&gt;

&lt;p&gt;Before filtering the customers, we first need to calculate the total amount spent by each customer.&lt;/p&gt;

&lt;p&gt;We can use a CTE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt;
        &lt;span class="n"&gt;customer_id&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="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_spent&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sales&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;customer_id&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;total_spent&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;total_spent&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CTE produces an intermediate result similar to:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;total_spent&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;45000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;45000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;10000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The main query then filters this result:&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;total_spent&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;total_spent&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;30000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;giving us:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;total_spent&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;45000&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;45000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This demonstrates an important advantage of CTEs: we can perform one analytical step, give the result a meaningful name, and then continue our analysis using that result.&lt;/p&gt;




&lt;h3&gt;
  
  
  Using Multiple CTEs
&lt;/h3&gt;

&lt;p&gt;We are not limited to creating only one CTE.&lt;/p&gt;

&lt;p&gt;SQL allows us to define multiple CTEs within the same statement by separating them with commas.&lt;/p&gt;

&lt;p&gt;The general structure is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;cte_one&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;cte_two&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;cte_one&lt;/span&gt;
&lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;cte_two&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="p"&gt;...;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can be particularly useful when solving a problem that contains several analytical steps.&lt;/p&gt;

&lt;p&gt;Suppose we want to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Calculate the total amount spent by each customer.&lt;/li&gt;
&lt;li&gt;Calculate the average customer spending.&lt;/li&gt;
&lt;li&gt;Identify customers who spent more than the average customer.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We can break the problem into logical steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt;
        &lt;span class="n"&gt;customer_id&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="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_spent&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sales&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;customer_id&lt;/span&gt;
&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="n"&gt;average_spending&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt;
        &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;total_spent&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;avg_spent&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_spent&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;average_spending&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;cs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total_spent&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avg_spent&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the second CTE can reference the result produced by the first CTE.&lt;/p&gt;

&lt;p&gt;Conceptually, our query follows this process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Raw Sales Data
      ↓
Calculate spending per customer
      ↓
Calculate average customer spending
      ↓
Compare each customer with the average
      ↓
Return above-average customers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of trying to solve the entire problem in one deeply nested query, CTEs allow us to express the analysis as a sequence of understandable steps.&lt;/p&gt;

&lt;p&gt;This is one of the main reasons CTEs are popular when writing analytical SQL.&lt;/p&gt;




&lt;h2&gt;
  
  
  Subqueries vs CTEs
&lt;/h2&gt;

&lt;p&gt;At this point, you may be wondering:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If both subqueries and CTEs can produce intermediate results, which one should I use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer depends on the problem you are solving.&lt;/p&gt;

&lt;p&gt;Consider our original employee example.&lt;/p&gt;

&lt;p&gt;Using a subquery:&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;employee_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;salary&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using a CTE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;average_salary&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;avg_salary&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;employee_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;
&lt;span class="k"&gt;CROSS&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;average_salary&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;avg_salary&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both can produce the same result.&lt;/p&gt;

&lt;p&gt;The main difference here is how the query is organized.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Subquery&lt;/th&gt;
&lt;th&gt;CTE&lt;/th&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Location&lt;/td&gt;
&lt;td&gt;Nested inside another query&lt;/td&gt;
&lt;td&gt;Defined before the main query using WITH&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Readability&lt;/td&gt;
&lt;td&gt;Good for simple queries&lt;/td&gt;
&lt;td&gt;Often clearer for complex queries&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Nesting&lt;/td&gt;
&lt;td&gt;Can become difficult to read when heavily nested&lt;/td&gt;
&lt;td&gt;Can break complex logic into named steps&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Reuse within the same statement&lt;/td&gt;
&lt;td&gt;Often requires repeating the subquery&lt;/td&gt;
&lt;td&gt;A CTE can often be referenced multiple times&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Recursive queries&lt;/td&gt;
&lt;td&gt;Not normally used for recursion&lt;/td&gt;
&lt;td&gt;Recursive CTEs can handle hierarchical problems&lt;/td&gt;
&lt;/tr&gt;

&lt;tr&gt;
&lt;td&gt;Lifetime&lt;/td&gt;
&lt;td&gt;Exists only as part of its containing statement&lt;/td&gt;
&lt;td&gt;Exists only for the statement in which it is defined&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It is important to note that a CTE is &lt;strong&gt;not automatically faster&lt;/strong&gt; than a subquery.&lt;/p&gt;

&lt;p&gt;Modern database engines have query optimizers that determine how SQL statements should actually be executed. Depending on the database system and the query, a CTE may be inlined, materialized, or optimized in another way.&lt;/p&gt;

&lt;p&gt;Therefore, CTEs should not automatically be chosen because they are assumed to improve performance.&lt;/p&gt;

&lt;p&gt;Their biggest advantage is often &lt;strong&gt;clarity and organization&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  When Should You Use a Subquery?
&lt;/h2&gt;

&lt;p&gt;Subqueries work particularly well when the intermediate calculation is relatively simple and is needed in only one place.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;product_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The logic is straightforward:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find the average price and return products priced above it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Writing a separate CTE may add unnecessary complexity to such a simple query.&lt;/p&gt;

&lt;p&gt;Subqueries are commonly useful when working with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;WHERE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HAVING&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SELECT&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;FROM&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;IN&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;EXISTS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;NOT EXISTS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Comparison operators such as &lt;code&gt;&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;&lt;/code&gt;, and &lt;code&gt;=&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  When Should You Use a CTE?
&lt;/h2&gt;

&lt;p&gt;CTEs become especially useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A query contains several logical steps.&lt;/li&gt;
&lt;li&gt;The same intermediate result needs to be referenced more than once.&lt;/li&gt;
&lt;li&gt;Nested subqueries are becoming difficult to understand.&lt;/li&gt;
&lt;li&gt;You want to give intermediate calculations meaningful names.&lt;/li&gt;
&lt;li&gt;You are working with hierarchical or recursive data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, names such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer_spending
monthly_revenue
department_average
top_customers
regional_sales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;immediately communicate what each part of the query represents.&lt;/p&gt;

&lt;p&gt;Compare that with several layers of unnamed nested queries.&lt;/p&gt;

&lt;p&gt;A well-structured CTE can make complex analytical SQL read almost like a sequence of instructions.&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Mistakes When Using Subqueries and CTEs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Returning Multiple Values Where One Is Expected
&lt;/h3&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'IT'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the IT department contains several employees with different salaries, the subquery may return multiple rows.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;=&lt;/code&gt; expects a single value.&lt;/p&gt;

&lt;p&gt;Depending on the intended question, an operator such as &lt;code&gt;IN&lt;/code&gt; may be more appropriate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;salary&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'IT'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always think about whether your subquery is expected to return &lt;strong&gt;one value, one row, or multiple rows&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Making Subqueries Unnecessarily Deep
&lt;/h3&gt;

&lt;p&gt;A query containing many levels of nested subqueries can quickly become difficult to understand.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Query
 └── Subquery
      └── Subquery
           └── Subquery
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the logic becomes difficult to follow, consider restructuring the query using CTEs.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Forgetting That a CTE Is Temporary
&lt;/h3&gt;

&lt;p&gt;A CTE is available only to the SQL statement immediately associated with it.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;WITH&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt;
        &lt;span class="n"&gt;customer_id&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="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;total_spent&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;sales&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;customer_id&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this statement finishes, you cannot run a separate query such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customer_spending&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and expect the CTE still to exist.&lt;/p&gt;

&lt;p&gt;If you need to permanently store a result, you may need a table, view, or another database object depending on your requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Assuming CTEs Are Always Faster
&lt;/h3&gt;

&lt;p&gt;CTEs are excellent for organizing SQL, but they do not automatically improve query performance.&lt;/p&gt;

&lt;p&gt;Performance depends on factors such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The database management system&lt;/li&gt;
&lt;li&gt;Available indexes&lt;/li&gt;
&lt;li&gt;Table sizes&lt;/li&gt;
&lt;li&gt;Join conditions&lt;/li&gt;
&lt;li&gt;Filtering&lt;/li&gt;
&lt;li&gt;Aggregations&lt;/li&gt;
&lt;li&gt;Query execution plans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use CTEs primarily when they make your SQL logic clearer, and investigate the execution plan when performance matters.&lt;/p&gt;




&lt;h2&gt;
  
  
  Putting Everything Together
&lt;/h2&gt;

&lt;p&gt;Subqueries and CTEs ultimately help us solve the same fundamental problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;How can we use the result of one query as part of a larger analytical question?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A subquery places one query inside another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Outer Query
     ↓
(Subquery)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A CTE takes a more step-by-step approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WITH intermediate_result AS (...)
              ↓
         Main Query
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither approach is universally better.&lt;/p&gt;

&lt;p&gt;For a short calculation that is used once, a subquery may be the simplest solution.&lt;/p&gt;

&lt;p&gt;For an analysis containing several intermediate calculations, a CTE can make the logic significantly easier to follow.&lt;/p&gt;




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

&lt;p&gt;As SQL queries become more advanced, business questions rarely require just one simple &lt;code&gt;SELECT&lt;/code&gt; statement.&lt;/p&gt;

&lt;p&gt;You may need to calculate an average before filtering records, summarize customer transactions before comparing spending patterns, or perform several intermediate calculations before producing the final result.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;subqueries and Common Table Expressions (CTEs)&lt;/strong&gt; become valuable.&lt;/p&gt;

&lt;p&gt;Subqueries allow us to place one query inside another and use the result as part of a larger SQL operation. They are particularly useful for concise calculations and filtering based on dynamically generated values.&lt;/p&gt;

&lt;p&gt;CTEs, on the other hand, allow us to break more complex SQL logic into &lt;strong&gt;named, logical steps&lt;/strong&gt; using the &lt;code&gt;WITH&lt;/code&gt; keyword. This can make analytical queries easier to read, understand, debug, and maintain.&lt;/p&gt;

&lt;p&gt;The easiest way to remember the distinction is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A subquery nests the logic, while a CTE names and organizes the logic.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As a data analyst, you do not need to choose one approach for every situation. The important skill is understanding the problem, recognizing the shape of the intermediate result you need, and selecting the approach that expresses your logic most clearly.&lt;/p&gt;

&lt;p&gt;Once you are comfortable with subqueries and CTEs, you are ready to tackle more advanced SQL techniques such as &lt;strong&gt;window functions, recursive CTEs, ranking, and multi-step analytical queries&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>database</category>
      <category>data</category>
      <category>beginners</category>
    </item>
    <item>
      <title>WHAT IS SQL JOINS</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Sun, 20 Sep 2026 16:03:04 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/what-is-sql-joins-3i65</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/what-is-sql-joins-3i65</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Imagine walking into a car dealership and asking the manager:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“Which customers bought which cars, how much did they spend, and which salesperson handled each sale?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The information needed to answer this question might already exist in the company's database — but there is a catch.&lt;/p&gt;

&lt;p&gt;It is not necessarily stored in one place.&lt;/p&gt;

&lt;p&gt;Customer information might be stored in a &lt;code&gt;customers&lt;/code&gt; table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Mary Atieno&lt;/td&gt;
&lt;td&gt;Kisumu&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Information about sales might be stored separately in a &lt;code&gt;sales&lt;/code&gt; table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;car_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;C10&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;C15&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;C12&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And information about the cars might exist in yet another table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;car_id&lt;/th&gt;
&lt;th&gt;make&lt;/th&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;C10&lt;/td&gt;
&lt;td&gt;Toyota&lt;/td&gt;
&lt;td&gt;Hilux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C12&lt;/td&gt;
&lt;td&gt;Ford&lt;/td&gt;
&lt;td&gt;Ranger&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;C15&lt;/td&gt;
&lt;td&gt;Mazda&lt;/td&gt;
&lt;td&gt;CX-5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Each table tells us something useful, but none of them can answer our original question on its own.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;customers&lt;/code&gt; table knows &lt;strong&gt;who the customers are&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;sales&lt;/code&gt; table knows &lt;strong&gt;what transactions occurred&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;cars&lt;/code&gt; table knows &lt;strong&gt;which vehicles were sold&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;What connects these pieces of information?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL JOINs.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A JOIN allows us to combine related information stored across different tables by identifying columns that connect those tables.&lt;/p&gt;

&lt;p&gt;In our example, &lt;code&gt;customer_id&lt;/code&gt; connects customers to their sales:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customers                         sales
─────────                         ─────
customer_id ───────────────────► customer_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly, &lt;code&gt;car_id&lt;/code&gt; connects a sale to information about the vehicle:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sales                             cars
─────                             ────
car_id ─────────────────────────► car_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once these relationships are understood, SQL can bring the information together and allow us to answer questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which customer purchased each vehicle?&lt;/li&gt;
&lt;li&gt;Which cars generated the most revenue?&lt;/li&gt;
&lt;li&gt;Which customers have never made a purchase?&lt;/li&gt;
&lt;li&gt;Which vehicles have never been sold?&lt;/li&gt;
&lt;li&gt;How much has each customer spent?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one of the reasons JOINs are such an important SQL skill. Real-world databases rarely store everything in one giant table. Instead, data is often separated into related tables, and analysts need to know how to bring the right information together.&lt;/p&gt;

&lt;p&gt;In this article, we will explore the major types of SQL JOINs — &lt;strong&gt;INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, CROSS JOIN, and SELF JOIN&lt;/strong&gt; — using practical examples to understand not only &lt;strong&gt;how they work, but when and why we use them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's connect the tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before We Join: Understanding Keys and Table Relationships
&lt;/h2&gt;

&lt;p&gt;Before writing our first SQL JOIN, we need to understand one important question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How does SQL know which rows from one table should be connected to rows in another table?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The answer lies in &lt;strong&gt;keys&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;A &lt;strong&gt;primary key&lt;/strong&gt; is a column, or combination of columns, that uniquely identifies each record in a table.&lt;/p&gt;

&lt;p&gt;Consider our &lt;code&gt;customers&lt;/code&gt; table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Mary Atieno&lt;/td&gt;
&lt;td&gt;Kisumu&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here, &lt;code&gt;customer_id&lt;/code&gt; is the primary key.&lt;/p&gt;

&lt;p&gt;Each customer has a unique ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;James Mwangi  → 101
Faith Chebet  → 102
Mary Atieno   → 103
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if two customers happen to have the same name, their &lt;code&gt;customer_id&lt;/code&gt; values should still be different.&lt;/p&gt;

&lt;p&gt;A table can be created with a primary key like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;customer_name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;county&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;PRIMARY KEY&lt;/code&gt; constraint tells the database that &lt;code&gt;customer_id&lt;/code&gt; should uniquely identify each customer.&lt;/p&gt;




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

&lt;p&gt;A &lt;strong&gt;foreign key&lt;/strong&gt; is a column in one table that references a primary key, or another unique key, in another table.&lt;/p&gt;

&lt;p&gt;Consider our &lt;code&gt;sales&lt;/code&gt; table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;car_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;C10&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;C15&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;C12&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code&gt;customer_id&lt;/code&gt; column appears here again.&lt;/p&gt;

&lt;p&gt;But this time, it is being used to identify &lt;strong&gt;which customer made each purchase&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We can visualize the connection like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CUSTOMERS                         SALES

customer_id                      customer_id
───────────                      ───────────
101 James Mwangi  ────────────► 101
102 Faith Chebet  ────────────► 102
103 Mary Atieno   ────────────► 103
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;customers&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer_id = Primary Key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;sales&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customer_id = Foreign Key
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This relationship allows us to connect customer information with sales information.&lt;/p&gt;




&lt;h2&gt;
  
  
  Understanding the Relationship
&lt;/h2&gt;

&lt;p&gt;One customer can make several purchases.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customers&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Sales&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;2,200,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice that &lt;code&gt;customer_id 101&lt;/code&gt; appears twice in the &lt;code&gt;sales&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;That is perfectly acceptable because James has made two purchases.&lt;/p&gt;

&lt;p&gt;The relationship can therefore be described as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CUSTOMERS                     SALES

    ONE                        MANY

     101  ────────────────┬── S001
                          │
                          └── S002
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is known as a &lt;strong&gt;one-to-many relationship&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;One customer can be associated with many sales, while each sale in this example belongs to one customer.&lt;/p&gt;




&lt;h2&gt;
  
  
  The JOIN Condition
&lt;/h2&gt;

&lt;p&gt;Now that we know how the tables are related, we can tell SQL how to connect them.&lt;/p&gt;

&lt;p&gt;This is done using the &lt;code&gt;ON&lt;/code&gt; condition.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&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;sales&lt;/span&gt;
    &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sales&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;The most important part for now is:&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;ON&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are essentially telling SQL:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Match a customer with a sale whenever their &lt;code&gt;customer_id&lt;/code&gt; values are equal.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;SQL compares the values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;customers.customer_id       sales.customer_id

        101        =               101       ✓
        102        =               102       ✓
        103        =               103       ✓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once SQL finds the matching values, it can combine information from both tables.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Not Join Using Customer Names?
&lt;/h2&gt;

&lt;p&gt;You might wonder why we cannot simply write:&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;ON&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;customer_name&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Names are not always reliable identifiers.&lt;/p&gt;

&lt;p&gt;Two customers could have the same name, names may be misspelled, or a customer's name could change.&lt;/p&gt;

&lt;p&gt;IDs are generally more reliable for establishing relationships between tables.&lt;/p&gt;

&lt;p&gt;That is why relational databases commonly use &lt;strong&gt;primary and foreign keys&lt;/strong&gt; to connect related records.&lt;/p&gt;




&lt;h2&gt;
  
  
  Our Database Relationship
&lt;/h2&gt;

&lt;p&gt;For the examples in this article, we will work with three tables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CUSTOMERS
──────────────
customer_id (PK)
customer_name
county
       │
       │ customer_id
       ▼
SALES
──────────────
sale_id (PK)
customer_id (FK)
car_id (FK)
amount
       │
       │ car_id
       ▼
CARS
──────────────
car_id (PK)
make
model
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;PK&lt;/code&gt; represents a &lt;strong&gt;Primary Key&lt;/strong&gt;, while &lt;code&gt;FK&lt;/code&gt; represents a &lt;strong&gt;Foreign Key&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Now that we understand how the tables are connected, we are ready to start joining them.&lt;/p&gt;

&lt;p&gt;The first and perhaps most fundamental type of JOIN we will explore is the &lt;strong&gt;INNER JOIN&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. INNER JOIN — Finding Matching Records
&lt;/h2&gt;

&lt;p&gt;Now that we understand how tables are connected using keys, let's look at our first type of JOIN: the &lt;strong&gt;INNER JOIN&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;INNER JOIN&lt;/code&gt; returns only the records that have &lt;strong&gt;matching values in both tables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If a record does not have a match in both tables, it will not appear in the result.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's look at an example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Our Customers Table
&lt;/h3&gt;

&lt;p&gt;Suppose we have the following customers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Mary Atieno&lt;/td&gt;
&lt;td&gt;Kisumu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;Brian Otieno&lt;/td&gt;
&lt;td&gt;Mombasa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Our Sales Table
&lt;/h3&gt;

&lt;p&gt;Now consider the sales records:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice something important.&lt;/p&gt;

&lt;p&gt;Customers &lt;code&gt;101&lt;/code&gt;, &lt;code&gt;102&lt;/code&gt;, and &lt;code&gt;103&lt;/code&gt; have corresponding records in the &lt;code&gt;sales&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;However, customer &lt;code&gt;104&lt;/code&gt;, Brian Otieno, does not have a sales record.&lt;/p&gt;

&lt;p&gt;If we use an &lt;code&gt;INNER JOIN&lt;/code&gt;, SQL will return only customers who have matching sales records.&lt;/p&gt;

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

&lt;p&gt;We can join the two tables using:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="e78n4k"&lt;br&gt;
SELECT&lt;br&gt;
    customers.customer_name,&lt;br&gt;
    customers.county,&lt;br&gt;
    sales.sale_id,&lt;br&gt;
    sales.amount&lt;br&gt;
FROM customers&lt;br&gt;
INNER JOIN sales&lt;br&gt;
    ON customers.customer_id = sales.customer_id;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The most important part is:



```sql id="6a3c2f"
ON customers.customer_id = sales.customer_id
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This tells SQL to compare the &lt;code&gt;customer_id&lt;/code&gt; column in the &lt;code&gt;customers&lt;/code&gt; table with the &lt;code&gt;customer_id&lt;/code&gt; column in the &lt;code&gt;sales&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Conceptually, SQL is looking for matches:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="z4ub62"&lt;br&gt;
CUSTOMERS                         SALES&lt;/p&gt;

&lt;p&gt;101 James Mwangi  ────────────── 101 S001 ✓&lt;br&gt;
102 Faith Chebet  ────────────── 102 S003 ✓&lt;br&gt;
103 Mary Atieno   ────────────── 103 S002 ✓&lt;br&gt;
104 Brian Otieno                 No match ✗&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Because Brian does not have a matching record in `sales`, he will not appear in the result.

### Result

The query produces:

| customer_name | county  | sale_id |    amount |
| ------------- | ------- | ------- | --------: |
| James Mwangi  | Nairobi | S001    | 3,500,000 |
| Faith Chebet  | Nakuru  | S003    | 4,100,000 |
| Mary Atieno   | Kisumu  | S002    | 2,800,000 |

Only records with matches in **both tables** have been returned.

---

### Using Table Aliases

Writing the complete table names repeatedly can make SQL queries unnecessarily long.

Instead of:



```sql id="8m4qu7"
SELECT
    customers.customer_name,
    customers.county,
    sales.sale_id,
    sales.amount
FROM customers
INNER JOIN sales
    ON customers.customer_id = sales.customer_id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;we can assign shorter names called &lt;strong&gt;aliases&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="qk7m9p"&lt;br&gt;
SELECT&lt;br&gt;
    c.customer_name,&lt;br&gt;
    c.county,&lt;br&gt;
    s.sale_id,&lt;br&gt;
    s.amount&lt;br&gt;
FROM customers AS c&lt;br&gt;
INNER JOIN sales AS s&lt;br&gt;
    ON c.customer_id = s.customer_id;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Here:



```text id="5o8by4"
c → customers
s → sales
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The query performs exactly the same operation, but it is shorter and easier to read.&lt;/p&gt;

&lt;p&gt;Aliases become particularly useful when joining several tables.&lt;/p&gt;


&lt;h2&gt;
  
  
  Joining More Than Two Tables
&lt;/h2&gt;

&lt;p&gt;What if we also want to know &lt;strong&gt;which car each customer purchased?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;sales&lt;/code&gt; table contains a &lt;code&gt;car_id&lt;/code&gt;, which connects it to the &lt;code&gt;cars&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;We can therefore join all three tables:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="6v8q3f"&lt;br&gt;
SELECT&lt;br&gt;
    c.customer_name,&lt;br&gt;
    c.county,&lt;br&gt;
    ca.make,&lt;br&gt;
    ca.model,&lt;br&gt;
    s.amount&lt;br&gt;
FROM sales AS s&lt;br&gt;
INNER JOIN customers AS c&lt;br&gt;
    ON s.customer_id = c.customer_id&lt;br&gt;
INNER JOIN cars AS ca&lt;br&gt;
    ON s.car_id = ca.car_id;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Now SQL follows the relationships:



```text id="79om1b"
CUSTOMERS
    │
    │ customer_id
    ▼
  SALES
    │
    │ car_id
    ▼
   CARS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The result could look like:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;th&gt;make&lt;/th&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;td&gt;Toyota&lt;/td&gt;
&lt;td&gt;Hilux&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;td&gt;Ford&lt;/td&gt;
&lt;td&gt;Ranger&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mary Atieno&lt;/td&gt;
&lt;td&gt;Kisumu&lt;/td&gt;
&lt;td&gt;Mazda&lt;/td&gt;
&lt;td&gt;CX-5&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We can now answer a much more meaningful business question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which customer purchased which car, and how much did they spend?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This demonstrates the real power of SQL JOINs. Information that was separated across multiple tables can now be analysed together.&lt;/p&gt;


&lt;h2&gt;
  
  
  When Would You Use an INNER JOIN?
&lt;/h2&gt;

&lt;p&gt;An &lt;code&gt;INNER JOIN&lt;/code&gt; is useful when you are interested only in records that have corresponding information in both tables.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customers who have made purchases&lt;/li&gt;
&lt;li&gt;Employees assigned to departments&lt;/li&gt;
&lt;li&gt;Products that have been ordered&lt;/li&gt;
&lt;li&gt;Students enrolled in courses&lt;/li&gt;
&lt;li&gt;Drivers who have completed trips&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple way to remember it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;INNER JOIN = Give me the matches.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But what happens if we want to see &lt;strong&gt;all customers&lt;/strong&gt;, including those who have never purchased anything?&lt;/p&gt;

&lt;p&gt;An &lt;code&gt;INNER JOIN&lt;/code&gt; cannot give us that complete picture.&lt;/p&gt;

&lt;p&gt;For that, we need our next JOIN: the &lt;strong&gt;LEFT JOIN&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. LEFT JOIN — Keeping Everything from the Left Table
&lt;/h2&gt;

&lt;p&gt;In the previous section, we saw that an &lt;code&gt;INNER JOIN&lt;/code&gt; returns only records that have matching values in both tables.&lt;/p&gt;

&lt;p&gt;But sometimes we want a different answer.&lt;/p&gt;

&lt;p&gt;Suppose management asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“Show me all our customers, including those who have never made a purchase.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An &lt;code&gt;INNER JOIN&lt;/code&gt; would not work because customers without a matching sales record would be excluded.&lt;/p&gt;

&lt;p&gt;This is where a &lt;strong&gt;LEFT JOIN&lt;/strong&gt; becomes useful.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;LEFT JOIN&lt;/code&gt; returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;All records from the left table&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Matching records from the right table&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NULL&lt;/code&gt; where a record from the left table has no corresponding match in the right table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple way to remember this is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;LEFT JOIN = Keep everything on the left and bring matching information from the right.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Our Two Tables
&lt;/h3&gt;

&lt;p&gt;Let's continue using the &lt;code&gt;customers&lt;/code&gt; and &lt;code&gt;sales&lt;/code&gt; tables.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Customers&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Mary Atieno&lt;/td&gt;
&lt;td&gt;Kisumu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;Brian Otieno&lt;/td&gt;
&lt;td&gt;Mombasa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Sales&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice again that Brian Otieno (&lt;code&gt;customer_id = 104&lt;/code&gt;) does not have a corresponding record in the &lt;code&gt;sales&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;With an &lt;code&gt;INNER JOIN&lt;/code&gt;, Brian was excluded.&lt;/p&gt;

&lt;p&gt;Let's see what happens with a &lt;code&gt;LEFT JOIN&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  LEFT JOIN Syntax
&lt;/h3&gt;



&lt;p&gt;```sql id="w5w92z"&lt;br&gt;
SELECT&lt;br&gt;
    c.customer_id,&lt;br&gt;
    c.customer_name,&lt;br&gt;
    c.county,&lt;br&gt;
    s.sale_id,&lt;br&gt;
    s.amount&lt;br&gt;
FROM customers AS c&lt;br&gt;
LEFT JOIN sales AS s&lt;br&gt;
    ON c.customer_id = s.customer_id;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Here, `customers` is the **left table** because it appears before `LEFT JOIN`.



```text id="mmx2r8"
customers                     sales
   LEFT                       RIGHT
     │                          │
     └──────── LEFT JOIN ───────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQL keeps every record from &lt;code&gt;customers&lt;/code&gt; and then looks for matching sales information.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="77dtb4"&lt;br&gt;
CUSTOMERS                         SALES&lt;/p&gt;

&lt;p&gt;101 James Mwangi  ────────────── 101 S001 ✓&lt;br&gt;
102 Faith Chebet  ────────────── 102 S003 ✓&lt;br&gt;
103 Mary Atieno   ────────────── 103 S002 ✓&lt;br&gt;
104 Brian Otieno                 No match&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The important difference is that Brian is **not removed** from the result.

### Result

| customer_id | customer_name | county  | sale_id |    amount |
| ----------: | ------------- | ------- | ------- | --------: |
|         101 | James Mwangi  | Nairobi | S001    | 3,500,000 |
|         102 | Faith Chebet  | Nakuru  | S003    | 4,100,000 |
|         103 | Mary Atieno   | Kisumu  | S002    | 2,800,000 |
|         104 | Brian Otieno  | Mombasa | NULL    |      NULL |

Because Brian has no matching sale, SQL cannot provide a `sale_id` or `amount`.

Instead, those values appear as:



```text id="0n3m8g"
NULL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In SQL, &lt;code&gt;NULL&lt;/code&gt; represents a &lt;strong&gt;missing or unknown value&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It is not the same as:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="cf1e11"&lt;br&gt;
0&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


and it is not the same as an empty string.

In this example, the `NULL` values tell us something useful: **Brian has no matching sales record.**

---

## Finding Customers Who Have Never Purchased

LEFT JOIN becomes especially useful when we combine it with `IS NULL`.

Suppose management asks:

&amp;gt; **“Which customers have never made a purchase?”**

We can write:



```sql id="xxo5ox"
SELECT
    c.customer_id,
    c.customer_name,
    c.county
FROM customers AS c
LEFT JOIN sales AS s
    ON c.customer_id = s.customer_id
WHERE s.customer_id IS NULL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The result would be:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;Brian Otieno&lt;/td&gt;
&lt;td&gt;Mombasa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This technique is extremely useful in real-world analysis.&lt;/p&gt;

&lt;p&gt;For example, we could use it to find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Customers who have never purchased&lt;/li&gt;
&lt;li&gt;Products that have never been sold&lt;/li&gt;
&lt;li&gt;Employees who have not been assigned to a department&lt;/li&gt;
&lt;li&gt;Vehicles that have never completed a trip&lt;/li&gt;
&lt;li&gt;Students who have not registered for a course&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  What Happens When One Customer Has Multiple Sales?
&lt;/h2&gt;

&lt;p&gt;Suppose James makes another purchase.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;sales&lt;/code&gt; table becomes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S004&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;2,000,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;When we run our &lt;code&gt;LEFT JOIN&lt;/code&gt;, James appears twice:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;S004&lt;/td&gt;
&lt;td&gt;2,000,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mary Atieno&lt;/td&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Brian Otieno&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;td&gt;NULL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is not SQL accidentally creating a duplicate.&lt;/p&gt;

&lt;p&gt;James has &lt;strong&gt;two matching records&lt;/strong&gt; in the &lt;code&gt;sales&lt;/code&gt; table, so SQL returns one result row for each match.&lt;/p&gt;

&lt;p&gt;This is an important concept when working with one-to-many relationships.&lt;/p&gt;


&lt;h2&gt;
  
  
  INNER JOIN vs LEFT JOIN
&lt;/h2&gt;

&lt;p&gt;We can now clearly see the difference between the first two JOINs.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;INNER JOIN&lt;/th&gt;
&lt;th&gt;LEFT JOIN&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Returns matching records only&lt;/td&gt;
&lt;td&gt;Returns all left-table records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Unmatched left records disappear&lt;/td&gt;
&lt;td&gt;Unmatched left records remain&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Useful when only matches matter&lt;/td&gt;
&lt;td&gt;Useful when missing matches also matter&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Consider Brian:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="97cx92"&lt;br&gt;
                    INNER JOIN      LEFT JOIN&lt;/p&gt;

&lt;p&gt;Brian Otieno            ✗               ✓&lt;br&gt;
Sales record            ✗               NULL&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


So if the question is:

**“Which customers have purchased something?”**

an `INNER JOIN` may be appropriate.

But if the question is:

**“Show me every customer and their purchases, if they have any,”**

a `LEFT JOIN` is more appropriate.

---

## A Common LEFT JOIN Mistake

Suppose we want all customers but only sales above KSh 3,000,000.

Consider:



```sql id="47e0f3"
SELECT
    c.customer_name,
    s.amount
FROM customers AS c
LEFT JOIN sales AS s
    ON c.customer_id = s.customer_id
WHERE s.amount &amp;gt; 3000000;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;WHERE&lt;/code&gt; condition removes rows where &lt;code&gt;s.amount&lt;/code&gt; is &lt;code&gt;NULL&lt;/code&gt;. As a result, customers without matching sales disappear, which can make the result behave more like an &lt;code&gt;INNER JOIN&lt;/code&gt; for this condition.&lt;/p&gt;

&lt;p&gt;If our intention is to retain all customers while matching only sales above KSh 3,000,000, we can place the condition inside the &lt;code&gt;ON&lt;/code&gt; clause:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="8oy89a"&lt;br&gt;
SELECT&lt;br&gt;
    c.customer_name,&lt;br&gt;
    s.amount&lt;br&gt;
FROM customers AS c&lt;br&gt;
LEFT JOIN sales AS s&lt;br&gt;
    ON c.customer_id = s.customer_id&lt;br&gt;
    AND s.amount &amp;gt; 3000000;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This preserves all customers from the left table while restricting which sales records qualify as matches.

Understanding where filtering happens is important when working with outer joins.

---

## When Should You Use a LEFT JOIN?

Use a `LEFT JOIN` when you want to keep **all records from your main table**, regardless of whether corresponding information exists in another table.

For a data analyst, LEFT JOIN is particularly useful when investigating **missing activity**.

For example:



```text id="6dq1k4"
All Customers
      ↓
LEFT JOIN
      ↓
Sales
      ↓
Customers with purchases
+
Customers without purchases
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A simple rule to remember is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;INNER JOIN asks: “Which records match?”&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;LEFT JOIN asks: “Give me everything on the left, whether it matches or not.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We have now seen what happens when we preserve the table on the &lt;strong&gt;left&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But what if we want to preserve every record from the table on the &lt;strong&gt;right&lt;/strong&gt; instead?&lt;/p&gt;

&lt;p&gt;That brings us to the &lt;strong&gt;RIGHT JOIN&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. RIGHT JOIN — Keeping Everything from the Right Table
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;RIGHT JOIN&lt;/strong&gt; works similarly to a &lt;code&gt;LEFT JOIN&lt;/code&gt;, but instead of keeping every record from the table on the left, it keeps &lt;strong&gt;every record from the table on the right&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;RIGHT JOIN&lt;/code&gt; returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All records from the &lt;strong&gt;right table&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Matching records from the &lt;strong&gt;left table&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NULL&lt;/code&gt; values where a right-table record does not have a corresponding match in the left table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple way to remember it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;RIGHT JOIN = Keep everything on the right and bring matching information from the left.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's continue with our &lt;code&gt;customers&lt;/code&gt; and &lt;code&gt;sales&lt;/code&gt; example.&lt;/p&gt;
&lt;h3&gt;
  
  
  Customers Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Mary Atieno&lt;/td&gt;
&lt;td&gt;Kisumu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;Brian Otieno&lt;/td&gt;
&lt;td&gt;Mombasa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Sales Table
&lt;/h3&gt;

&lt;p&gt;This time, imagine our &lt;code&gt;sales&lt;/code&gt; table contains:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S004&lt;/td&gt;
&lt;td&gt;105&lt;/td&gt;
&lt;td&gt;2,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Notice something unusual.&lt;/p&gt;

&lt;p&gt;The sale &lt;code&gt;S004&lt;/code&gt; references &lt;code&gt;customer_id = 105&lt;/code&gt;, but customer &lt;code&gt;105&lt;/code&gt; does not appear in our &lt;code&gt;customers&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;This could represent a data-quality problem, imported historical data, or—in a database without an enforced foreign-key constraint—an unmatched record.&lt;/p&gt;

&lt;p&gt;Let's see what happens when we use a &lt;code&gt;RIGHT JOIN&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  RIGHT JOIN Syntax
&lt;/h3&gt;



&lt;p&gt;```sql id="7d4n23"&lt;br&gt;
SELECT&lt;br&gt;
    c.customer_id,&lt;br&gt;
    c.customer_name,&lt;br&gt;
    c.county,&lt;br&gt;
    s.sale_id,&lt;br&gt;
    s.amount&lt;br&gt;
FROM customers AS c&lt;br&gt;
RIGHT JOIN sales AS s&lt;br&gt;
    ON c.customer_id = s.customer_id;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Here:



```text id="32j8fk"
customers                     sales
   LEFT                       RIGHT
     │                          │
     └──────── RIGHT JOIN ──────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Because &lt;code&gt;sales&lt;/code&gt; is the table on the &lt;strong&gt;right&lt;/strong&gt;, every sales record will be retained.&lt;/p&gt;

&lt;p&gt;SQL looks for matching customers:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="yk39du"&lt;br&gt;
CUSTOMERS                         SALES&lt;/p&gt;

&lt;p&gt;101 James Mwangi  ────────────── 101 S001 ✓&lt;br&gt;
102 Faith Chebet  ────────────── 102 S003 ✓&lt;br&gt;
103 Mary Atieno   ────────────── 103 S002 ✓&lt;br&gt;
                                  105 S004 ✗&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The sale for customer `105` does not have a matching customer record.

However, because we are using a `RIGHT JOIN`, the sale is still included.

### Result

| customer_id | customer_name | county  | sale_id |    amount |
| ----------: | ------------- | ------- | ------- | --------: |
|         101 | James Mwangi  | Nairobi | S001    | 3,500,000 |
|         103 | Mary Atieno   | Kisumu  | S002    | 2,800,000 |
|         102 | Faith Chebet  | Nakuru  | S003    | 4,100,000 |
|        NULL | NULL          | NULL    | S004    | 2,500,000 |

Notice the final row.

The sales information exists:



```text id="79hwha"
S004 → KSh 2,500,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;but SQL cannot find corresponding customer information.&lt;/p&gt;

&lt;p&gt;Therefore:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="i1a68m"&lt;br&gt;
customer_name → NULL&lt;br&gt;
county        → NULL&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


---

## Finding Sales Without Matching Customers

This can be useful when checking data quality.

For example:



```sql id="dhkqz5"
SELECT
    s.sale_id,
    s.customer_id,
    s.amount
FROM customers AS c
RIGHT JOIN sales AS s
    ON c.customer_id = s.customer_id
WHERE c.customer_id IS NULL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The result would be:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S004&lt;/td&gt;
&lt;td&gt;105&lt;/td&gt;
&lt;td&gt;2,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This tells us that sale &lt;code&gt;S004&lt;/code&gt; references a customer that cannot be found in the &lt;code&gt;customers&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;As a data analyst, this could be something worth investigating before performing further analysis.&lt;/p&gt;


&lt;h2&gt;
  
  
  RIGHT JOIN vs LEFT JOIN
&lt;/h2&gt;

&lt;p&gt;The main difference is simply &lt;strong&gt;which table must be preserved&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="3ew49g"&lt;br&gt;
LEFT JOIN&lt;/p&gt;

&lt;p&gt;CUSTOMERS  ← Keep everything&lt;br&gt;
    │&lt;br&gt;
    └──────── SALES&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Compared with:



```text id="rrk6mm"
RIGHT JOIN

CUSTOMERS ────────┐
                  │
              SALES ← Keep everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We can summarize them as:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;LEFT JOIN&lt;/th&gt;
&lt;th&gt;RIGHT JOIN&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Keeps all rows from the left table&lt;/td&gt;
&lt;td&gt;Keeps all rows from the right table&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Matches information from the right&lt;/td&gt;
&lt;td&gt;Matches information from the left&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Missing right-side values become &lt;code&gt;NULL&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Missing left-side values become &lt;code&gt;NULL&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;


&lt;h2&gt;
  
  
  Can a RIGHT JOIN Be Written as a LEFT JOIN?
&lt;/h2&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;This is an important observation.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="tg0sgr"&lt;br&gt;
SELECT *&lt;br&gt;
FROM customers AS c&lt;br&gt;
RIGHT JOIN sales AS s&lt;br&gt;
    ON c.customer_id = s.customer_id;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


We could simply reverse the table order:



```sql id="32frst"
SELECT *
FROM sales AS s
LEFT JOIN customers AS c
    ON s.customer_id = c.customer_id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Both queries express the same basic requirement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Keep every sales record and bring in customer information where a matching customer exists.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Because of this, many SQL developers and analysts prefer &lt;code&gt;LEFT JOIN&lt;/code&gt; for readability and consistency and simply change which table appears first.&lt;/p&gt;

&lt;p&gt;Nevertheless, understanding &lt;code&gt;RIGHT JOIN&lt;/code&gt; is important because you will encounter it in existing SQL queries and technical assessments.&lt;/p&gt;


&lt;h2&gt;
  
  
  When Should You Use a RIGHT JOIN?
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;RIGHT JOIN&lt;/code&gt; can be useful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every record from the right table must be retained.&lt;/li&gt;
&lt;li&gt;You want to identify records on the right that have no corresponding match on the left.&lt;/li&gt;
&lt;li&gt;The structure of an existing query makes keeping the right table convenient.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple way to remember the first three joins is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;INNER JOIN:&lt;/strong&gt; Keep the matches.&lt;br&gt;
&lt;strong&gt;LEFT JOIN:&lt;/strong&gt; Keep everything on the left.&lt;br&gt;
&lt;strong&gt;RIGHT JOIN:&lt;/strong&gt; Keep everything on the right.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But there is still one question left:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if we want to keep everything from both tables — whether the records match or not?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For that, we use a &lt;strong&gt;FULL OUTER JOIN&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. FULL OUTER JOIN — Keeping Everything from Both Tables
&lt;/h2&gt;

&lt;p&gt;So far, we have seen that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;INNER JOIN&lt;/code&gt; keeps only matching records.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;LEFT JOIN&lt;/code&gt; keeps all records from the left table.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RIGHT JOIN&lt;/code&gt; keeps all records from the right table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But what happens when we want to keep &lt;strong&gt;all records from both tables&lt;/strong&gt;, regardless of whether they have a match?&lt;/p&gt;

&lt;p&gt;This is where the &lt;strong&gt;FULL OUTER JOIN&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;FULL OUTER JOIN&lt;/code&gt; returns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Records that match in both tables&lt;/li&gt;
&lt;li&gt;Unmatched records from the left table&lt;/li&gt;
&lt;li&gt;Unmatched records from the right table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where no corresponding record exists, SQL returns &lt;code&gt;NULL&lt;/code&gt; for the missing values.&lt;/p&gt;

&lt;p&gt;A simple way to remember it is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;FULL OUTER JOIN = Give me everything from both tables and match what you can.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Our Customers Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;James Mwangi&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;Faith Chebet&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;Mary Atieno&lt;/td&gt;
&lt;td&gt;Kisumu&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;104&lt;/td&gt;
&lt;td&gt;Brian Otieno&lt;/td&gt;
&lt;td&gt;Mombasa&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Our Sales Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;sale_id&lt;/th&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;amount&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S001&lt;/td&gt;
&lt;td&gt;101&lt;/td&gt;
&lt;td&gt;3,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S002&lt;/td&gt;
&lt;td&gt;103&lt;/td&gt;
&lt;td&gt;2,800,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S003&lt;/td&gt;
&lt;td&gt;102&lt;/td&gt;
&lt;td&gt;4,100,000&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S004&lt;/td&gt;
&lt;td&gt;105&lt;/td&gt;
&lt;td&gt;2,500,000&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There are two important unmatched records:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="m7n3f8"&lt;br&gt;
Customer 104 → No sale&lt;br&gt;
Sale S004    → Customer 105 is not in customers&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


A `FULL OUTER JOIN` allows us to see both.

### FULL OUTER JOIN Syntax



```sql id="w4j2nv"
SELECT
    c.customer_id AS customer_record_id,
    c.customer_name,
    c.county,
    s.sale_id,
    s.customer_id AS sales_customer_id,
    s.amount
FROM customers AS c
FULL OUTER JOIN sales AS s
    ON c.customer_id = s.customer_id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;SQL first matches records where the &lt;code&gt;customer_id&lt;/code&gt; exists in both tables:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="zt28oc"&lt;br&gt;
CUSTOMERS                         SALES&lt;/p&gt;

&lt;p&gt;101 James Mwangi  ────────────── 101 S001 ✓&lt;br&gt;
102 Faith Chebet  ────────────── 102 S003 ✓&lt;br&gt;
103 Mary Atieno   ────────────── 103 S002 ✓&lt;/p&gt;

&lt;p&gt;104 Brian Otieno                 No match&lt;br&gt;
                                  105 S004&lt;br&gt;
                                  No match&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Unlike an `INNER JOIN`, neither unmatched record is discarded.

### Result

| customer_record_id | customer_name | county  | sale_id | sales_customer_id |    amount |
| -----------------: | ------------- | ------- | ------- | ----------------: | --------: |
|                101 | James Mwangi  | Nairobi | S001    |               101 | 3,500,000 |
|                102 | Faith Chebet  | Nakuru  | S003    |               102 | 4,100,000 |
|                103 | Mary Atieno   | Kisumu  | S002    |               103 | 2,800,000 |
|                104 | Brian Otieno  | Mombasa | NULL    |              NULL |      NULL |
|               NULL | NULL          | NULL    | S004    |               105 | 2,500,000 |

The result gives us three different situations.

### 1. Matching Records

For customers `101`, `102`, and `103`, SQL found matching records in both tables.

Their customer and sales information therefore appears together.

### 2. Customer Without a Sale

Brian Otieno (`customer_id = 104`) exists in the `customers` table but has no corresponding sale.

His sales information therefore appears as:



```text id="9k1qxr"
sale_id → NULL
amount  → NULL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Sale Without a Customer
&lt;/h3&gt;

&lt;p&gt;Sale &lt;code&gt;S004&lt;/code&gt; references &lt;code&gt;customer_id = 105&lt;/code&gt;, but that customer cannot be found in the &lt;code&gt;customers&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;Therefore, the customer information appears as &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This makes &lt;code&gt;FULL OUTER JOIN&lt;/code&gt; particularly useful when comparing datasets and looking for discrepancies.&lt;/p&gt;


&lt;h2&gt;
  
  
  Finding Only the Unmatched Records
&lt;/h2&gt;

&lt;p&gt;Sometimes we are not interested in the matches at all.&lt;/p&gt;

&lt;p&gt;Instead, we want to ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Which records exist in one table but do not have a corresponding record in the other?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We can combine &lt;code&gt;FULL OUTER JOIN&lt;/code&gt; with a &lt;code&gt;WHERE&lt;/code&gt; condition:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="h6v4np"&lt;br&gt;
SELECT&lt;br&gt;
    c.customer_id,&lt;br&gt;
    c.customer_name,&lt;br&gt;
    s.sale_id,&lt;br&gt;
    s.customer_id AS sales_customer_id&lt;br&gt;
FROM customers AS c&lt;br&gt;
FULL OUTER JOIN sales AS s&lt;br&gt;
    ON c.customer_id = s.customer_id&lt;br&gt;
WHERE c.customer_id IS NULL&lt;br&gt;
   OR s.customer_id IS NULL;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This would identify:



```text id="7d2u9b"
Brian Otieno → Customer without a sale
S004         → Sale without a matching customer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This type of query can be very useful during &lt;strong&gt;data validation, reconciliation, and data-quality checks&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Comparing the Four Main JOINs
&lt;/h2&gt;

&lt;p&gt;We can now bring together everything we have learned.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;JOIN&lt;/th&gt;
&lt;th&gt;Matching Rows&lt;/th&gt;
&lt;th&gt;Unmatched Left Rows&lt;/th&gt;
&lt;th&gt;Unmatched Right Rows&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;INNER JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;LEFT JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;RIGHT JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✗&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;FULL OUTER JOIN&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;td&gt;✓&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Another simple way to remember them is:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="21a5hx"&lt;br&gt;
INNER JOIN&lt;br&gt;
→ Keep only matches&lt;/p&gt;

&lt;p&gt;LEFT JOIN&lt;br&gt;
→ Keep matches + everything from the left&lt;/p&gt;

&lt;p&gt;RIGHT JOIN&lt;br&gt;
→ Keep matches + everything from the right&lt;/p&gt;

&lt;p&gt;FULL OUTER JOIN&lt;br&gt;
→ Keep everything from both sides&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The JOIN you choose should therefore depend on the **question you are trying to answer**, not simply on which syntax you remember.

For example:

**“Which customers have made purchases?”**

→ `INNER JOIN`

**“Show me all customers, including those who have never purchased.”**

→ `LEFT JOIN`

**“Keep every sales transaction, even if customer information is missing.”**

→ `RIGHT JOIN` — or equivalently restructure the query using a `LEFT JOIN`.

**“Show me all records from both datasets and highlight where information does not match.”**

→ `FULL OUTER JOIN`

Understanding these four JOINs gives you the foundation for combining related tables in SQL.

## Conclusion

SQL JOINs are an essential skill when working with relational databases because real-world data is often distributed across multiple related tables. Instead of storing customers, sales, products, employees, and other information in one large table, relational databases organize this information into separate tables that can be connected when needed.

In this article, we explored four important types of SQL JOINs:

* **INNER JOIN** — returns records that have matching values in both tables.
* **LEFT JOIN** — returns all records from the left table and matching records from the right table.
* **RIGHT JOIN** — returns all records from the right table and matching records from the left table.
* **FULL OUTER JOIN** — returns all records from both tables, whether they have a match or not.

The key to choosing the correct JOIN is to first understand the **question you are trying to answer**.

If you only need customers who have made purchases, an `INNER JOIN` may be appropriate. If you need all customers, including those who have never purchased anything, a `LEFT JOIN` would be more suitable. If you need to compare two datasets and identify both matching and unmatched records, a `FULL OUTER JOIN` can provide a more complete picture.

A simple way to remember the four JOINs is:



```text
INNER JOIN      → Keep the matches

LEFT JOIN       → Keep everything on the left

RIGHT JOIN      → Keep everything on the right

FULL OUTER JOIN → Keep everything from both sides
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, understanding JOIN syntax is only part of the skill. It is equally important to understand &lt;strong&gt;primary keys, foreign keys, table relationships, NULL values, and the level of detail in each table&lt;/strong&gt;. These concepts help ensure that tables are joined correctly and that the results of an analysis are reliable.&lt;/p&gt;

&lt;p&gt;For a data analyst, JOINs are particularly valuable because they allow data from different parts of a business to be brought together. A sales transaction can be connected to a customer, a customer to a location, a sale to a product, or an employee to a department. Once these connections are made, seemingly separate pieces of information can become meaningful business insights.&lt;/p&gt;

&lt;p&gt;The best way to become comfortable with SQL JOINs is through practice. Create a few related tables, experiment with each JOIN, examine the results, and ask yourself why certain records appeared while others did not.&lt;/p&gt;

&lt;p&gt;Ultimately, SQL JOINs are about one simple idea:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Connecting related pieces of data to reveal a more complete story.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>sql</category>
      <category>beginners</category>
      <category>database</category>
      <category>data</category>
    </item>
    <item>
      <title>INTRODUCTION TO SQL (DML &amp; DDL</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Sun, 20 Sep 2026 15:23:53 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/introduction-to-sql-dml-ddl-4p6b</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/introduction-to-sql-dml-ddl-4p6b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Every day, businesses and applications generate large amounts of data. Think about an online shop that needs to keep track of its customers, products, orders, and payments. This information needs to be stored in an organized way so that it can easily be accessed, updated, and analyzed. One common way of doing this is by using a &lt;strong&gt;relational database&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A relational database organizes data into &lt;strong&gt;tables&lt;/strong&gt;, which consist of rows and columns. For example, a company may have a &lt;code&gt;customers&lt;/code&gt; table containing customer information and an &lt;code&gt;orders&lt;/code&gt; table containing details about purchases made by those customers.&lt;/p&gt;

&lt;p&gt;To communicate with these databases, we use &lt;strong&gt;SQL (Structured Query Language)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;SQL is a language used to interact with relational databases. It allows us to perform tasks such as creating tables, adding new records, retrieving information, updating existing data, and deleting data that is no longer required.&lt;/p&gt;

&lt;p&gt;For example, imagine we have a table called &lt;code&gt;customers&lt;/code&gt;. If we wanted to see all the customers stored in that table, we could write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;customers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This simple SQL statement asks the database to return all the records from the &lt;code&gt;customers&lt;/code&gt; table.&lt;/p&gt;

&lt;p&gt;However, not all SQL commands perform the same type of task. Some commands are used to &lt;strong&gt;define and change the structure of a database&lt;/strong&gt;, while others are used to &lt;strong&gt;work with the data stored inside those structures&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;SQL commands are therefore commonly grouped into categories according to their purpose. Two important categories that every SQL beginner should understand are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DDL — Data Definition Language&lt;/strong&gt;, which is used to define and manage database structures.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DML — Data Manipulation Language&lt;/strong&gt;, which is used to add, modify, and remove data stored within those structures.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this article, we will explore DDL and DML using practical examples and learn how they work together when building and managing a relational database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Definition Language (DDL)
&lt;/h2&gt;

&lt;p&gt;Before we can store customer details, sales transactions, products, or any other information in a relational database, we first need to create a structure that will hold that data.&lt;/p&gt;

&lt;p&gt;This is where &lt;strong&gt;Data Definition Language (DDL)&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DDL (Data Definition Language)&lt;/strong&gt; is a category of SQL commands used to &lt;strong&gt;create, define, modify, and remove database objects and structures&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Database objects can include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Tables&lt;/li&gt;
&lt;li&gt;Schemas&lt;/li&gt;
&lt;li&gt;Views&lt;/li&gt;
&lt;li&gt;Indexes&lt;/li&gt;
&lt;li&gt;Sequences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a beginner, the easiest place to understand DDL is by working with &lt;strong&gt;tables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Imagine we are developing a database for a car dealership. Before we can add information about the cars available for sale, we need to create a table that defines what information should be stored.&lt;/p&gt;

&lt;p&gt;For example, we might want to store:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Car ID&lt;/li&gt;
&lt;li&gt;Make&lt;/li&gt;
&lt;li&gt;Model&lt;/li&gt;
&lt;li&gt;Year of manufacture&lt;/li&gt;
&lt;li&gt;Price&lt;/li&gt;
&lt;li&gt;Status&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;DDL allows us to create this structure before inserting the actual car records.&lt;/p&gt;

&lt;p&gt;The main DDL commands we will explore are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CREATE&lt;/code&gt; — creates a new database object.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ALTER&lt;/code&gt; — changes the structure of an existing database object.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;TRUNCATE&lt;/code&gt; — removes all records from a table while retaining its structure.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DROP&lt;/code&gt; — removes a database object completely.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  1. CREATE — Creating Database Objects
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;CREATE&lt;/code&gt; command is used to create new database objects.&lt;/p&gt;

&lt;p&gt;One of its most common uses is creating a table.&lt;/p&gt;

&lt;p&gt;The general syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="8o7rta"&lt;br&gt;
CREATE TABLE table_name (&lt;br&gt;
    column_name data_type constraints&lt;br&gt;
);&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Let's create a table called `cars`:



```sql id="o5ryy6"
CREATE TABLE cars (
    car_id SERIAL PRIMARY KEY,
    make VARCHAR(50) NOT NULL,
    model VARCHAR(50) NOT NULL,
    year_of_manufacture INT,
    price DECIMAL(12,2),
    status VARCHAR(30)
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;At this point, we have created the &lt;strong&gt;structure&lt;/strong&gt; of the table, but we have not added any car records.&lt;/p&gt;

&lt;p&gt;We can think of it like creating an empty spreadsheet:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;car_id&lt;/th&gt;
&lt;th&gt;make&lt;/th&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;year_of_manufacture&lt;/th&gt;
&lt;th&gt;price&lt;/th&gt;
&lt;th&gt;status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The columns exist, but there is no data yet.&lt;/p&gt;
&lt;h4&gt;
  
  
  Understanding the CREATE statement
&lt;/h4&gt;

&lt;p&gt;Let's break down some important parts.&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="jj9e0h"&lt;br&gt;
car_id SERIAL PRIMARY KEY&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


`car_id` is the name of the column.

`SERIAL` is a PostgreSQL feature commonly used to generate sequential integer values automatically.

`PRIMARY KEY` means that the column uniquely identifies each record in the table.

Next:



```sql id="o7i5fc"
make VARCHAR(50) NOT NULL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;VARCHAR(50)&lt;/code&gt; allows text values with a maximum length of 50 characters.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;NOT NULL&lt;/code&gt; means that this column must contain a value.&lt;/p&gt;

&lt;p&gt;And:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="5c9yte"&lt;br&gt;
price DECIMAL(12,2)&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


allows us to store decimal numbers, making it suitable for values such as prices.

Choosing appropriate **data types and constraints** is an important part of database design because they determine what kind of information can be stored in each column.

---

### 2. ALTER — Modifying an Existing Table

Database requirements can change over time.

Suppose we created our `cars` table but later realized that we also need to record the colour of each vehicle.

We do not necessarily need to delete and recreate the entire table.

Instead, we can use `ALTER TABLE`.



```sql id="8nmzoh"
ALTER TABLE cars
ADD COLUMN colour VARCHAR(30);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Our table structure now becomes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;car_id&lt;/th&gt;
&lt;th&gt;make&lt;/th&gt;
&lt;th&gt;model&lt;/th&gt;
&lt;th&gt;year_of_manufacture&lt;/th&gt;
&lt;th&gt;price&lt;/th&gt;
&lt;th&gt;status&lt;/th&gt;
&lt;th&gt;colour&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;ALTER TABLE&lt;/code&gt; can be used for several structural changes.&lt;/p&gt;

&lt;p&gt;For example, we can rename a column:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="r62ec9"&lt;br&gt;
ALTER TABLE cars&lt;br&gt;
RENAME COLUMN colour TO car_colour;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


We can also remove a column:



```sql id="81vzi4"
ALTER TABLE cars
DROP COLUMN car_colour;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Therefore, &lt;code&gt;ALTER&lt;/code&gt; is useful when the structure of an existing database object needs to change.&lt;/p&gt;


&lt;h3&gt;
  
  
  3. TRUNCATE — Removing All Records
&lt;/h3&gt;

&lt;p&gt;Suppose our &lt;code&gt;cars&lt;/code&gt; table contains hundreds of records and we want to remove &lt;strong&gt;all the rows&lt;/strong&gt; while keeping the table itself.&lt;/p&gt;

&lt;p&gt;We can use:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="m0xcr7"&lt;br&gt;
TRUNCATE TABLE cars;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


After executing the command, the table still exists:

| car_id | make | model | year_of_manufacture | price | status |
| ------ | ---- | ----- | ------------------- | ----- | ------ |
|        |      |       |                     |       |        |

The **structure remains**, but the records have been removed.

This distinction is important because `TRUNCATE` does not mean the same thing as `DROP`.

---

### 4. DROP — Removing a Database Object

The `DROP` command removes a database object completely.

For example:



```sql id="adwsm2"
DROP TABLE cars;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This removes the &lt;code&gt;cars&lt;/code&gt; table itself.&lt;/p&gt;

&lt;p&gt;After executing the statement, we can no longer query the table because its definition has been removed from the database.&lt;/p&gt;

&lt;p&gt;A simple way to remember the difference is:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TRUNCATE&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```text id="tv5mdv"&lt;br&gt;
Table&lt;br&gt;
├── Structure  ✓&lt;br&gt;
└── Records    ✗&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


**DROP**



```text id="ezcn2w"
Table
├── Structure  ✗
└── Records    ✗
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Because commands such as &lt;code&gt;DROP&lt;/code&gt; and &lt;code&gt;TRUNCATE&lt;/code&gt; can remove large amounts of data or entire database objects, they should be used carefully, particularly in production environments.&lt;/p&gt;


&lt;h2&gt;
  
  
  Putting DDL Together
&lt;/h2&gt;

&lt;p&gt;Let's look at the lifecycle of our table.&lt;/p&gt;

&lt;p&gt;First, we &lt;strong&gt;create&lt;/strong&gt; it:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="dl1qv5"&lt;br&gt;
CREATE TABLE cars (&lt;br&gt;
    car_id SERIAL PRIMARY KEY,&lt;br&gt;
    make VARCHAR(50),&lt;br&gt;
    model VARCHAR(50),&lt;br&gt;
    price DECIMAL(12,2)&lt;br&gt;
);&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Later, our requirements change, so we **alter** it:



```sql id="w1m2lg"
ALTER TABLE cars
ADD COLUMN status VARCHAR(30);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;If we want to remove all its records but keep the structure, we can use:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="a3ic11"&lt;br&gt;
TRUNCATE TABLE cars;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


And if the table itself is no longer required:



```sql id="n4nbbw"
DROP TABLE cars;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The four commands can therefore be summarized as:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Command&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Table Structure&lt;/th&gt;
&lt;th&gt;Data&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CREATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a new object&lt;/td&gt;
&lt;td&gt;Created&lt;/td&gt;
&lt;td&gt;Empty initially&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ALTER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changes an existing object's structure&lt;/td&gt;
&lt;td&gt;Modified&lt;/td&gt;
&lt;td&gt;Usually retained&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;TRUNCATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes all table records&lt;/td&gt;
&lt;td&gt;Retained&lt;/td&gt;
&lt;td&gt;Removed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DROP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Removes the database object&lt;/td&gt;
&lt;td&gt;Removed&lt;/td&gt;
&lt;td&gt;Removed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;DDL therefore provides the &lt;strong&gt;structure or foundation of our database&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once that structure exists, we can begin adding and working with actual records. This brings us to the next category of SQL commands: &lt;strong&gt;Data Manipulation Language (DML)&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Data Manipulation Language (DML)
&lt;/h2&gt;

&lt;p&gt;Once a database and its tables have been created, the next step is to work with the data stored inside those tables. This is where &lt;strong&gt;Data Manipulation Language (DML)&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DML (Data Manipulation Language)&lt;/strong&gt; refers to SQL commands used to &lt;strong&gt;add, modify, and remove data stored in database tables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of a database table like a spreadsheet. The table structure defines the columns available, while DML allows us to work with the individual records stored in the rows.&lt;/p&gt;

&lt;p&gt;For example, suppose we have the following &lt;code&gt;customers&lt;/code&gt; table:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;th&gt;email&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;John Kamau&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Mary Wanjiku&lt;/td&gt;
&lt;td&gt;Kiambu&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:mary@example.com"&gt;mary@example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Brian Kiptoo&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:brian@example.com"&gt;brian@example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The main DML commands we will explore are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;INSERT&lt;/code&gt; — adds new records to a table.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UPDATE&lt;/code&gt; — modifies existing records.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE&lt;/code&gt; — removes records from a table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will also look at &lt;code&gt;SELECT&lt;/code&gt;, which retrieves data from a database. &lt;code&gt;SELECT&lt;/code&gt; is sometimes taught alongside DML, although some SQL classifications place it in a separate category called &lt;strong&gt;DQL (Data Query Language)&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. INSERT — Adding Data
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;INSERT&lt;/code&gt; statement is used when we want to add new records to a table.&lt;/p&gt;

&lt;p&gt;The basic syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="5um3sm"&lt;br&gt;
INSERT INTO table_name (column1, column2, column3)&lt;br&gt;
VALUES (value1, value2, value3);&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Suppose a new customer named Alice joins our business. We could add her to the `customers` table using:



```sql id="98hspj"
INSERT INTO customers (customer_name, county, email)
VALUES ('Alice Njeri', 'Nairobi', 'alice@example.com');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Breaking this statement down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;INSERT INTO&lt;/code&gt; tells SQL that we want to add a new record.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;customers&lt;/code&gt; identifies the table receiving the data.&lt;/li&gt;
&lt;li&gt;The columns in parentheses specify where the values should be stored.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;VALUES&lt;/code&gt; contains the actual information being inserted.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After executing the statement, our table might contain:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;customer_id&lt;/th&gt;
&lt;th&gt;customer_name&lt;/th&gt;
&lt;th&gt;county&lt;/th&gt;
&lt;th&gt;email&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;John Kamau&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:john@example.com"&gt;john@example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;Mary Wanjiku&lt;/td&gt;
&lt;td&gt;Kiambu&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:mary@example.com"&gt;mary@example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Brian Kiptoo&lt;/td&gt;
&lt;td&gt;Nakuru&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:brian@example.com"&gt;brian@example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Alice Njeri&lt;/td&gt;
&lt;td&gt;Nairobi&lt;/td&gt;
&lt;td&gt;&lt;a href="mailto:alice@example.com"&gt;alice@example.com&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;We can also insert several records in a single statement:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="i4n3rx"&lt;br&gt;
INSERT INTO customers (customer_name, county, email)&lt;br&gt;
VALUES&lt;br&gt;
    ('Peter Otieno', 'Kisumu', '&lt;a href="mailto:peter@example.com"&gt;peter@example.com&lt;/a&gt;'),&lt;br&gt;
    ('Faith Chebet', 'Kericho', '&lt;a href="mailto:faith@example.com"&gt;faith@example.com&lt;/a&gt;'),&lt;br&gt;
    ('David Mwangi', 'Nyeri', '&lt;a href="mailto:david@example.com"&gt;david@example.com&lt;/a&gt;');&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This is known as inserting **multiple rows**.

---

### 2. UPDATE — Modifying Existing Data

Data stored in a database does not always remain the same. A customer might change their email address, move to another county, or update other personal details.

The `UPDATE` statement allows us to modify existing records.

Its basic syntax is:



```sql id="17l8gf"
UPDATE table_name
SET column_name = new_value
WHERE condition;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Suppose Alice moves from Nairobi to Nakuru. We could update her record using:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="e21cbr"&lt;br&gt;
UPDATE customers&lt;br&gt;
SET county = 'Nakuru'&lt;br&gt;
WHERE customer_id = 4;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The statement can be understood as:



```text id="8pn4ow"
UPDATE customers
        ↓
Which table?

SET county = 'Nakuru'
        ↓
What should change?

WHERE customer_id = 4
        ↓
Which record should change?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;WHERE&lt;/code&gt; clause is extremely important because it determines which rows are affected.&lt;/p&gt;

&lt;p&gt;Consider the following statement:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="r1v61y"&lt;br&gt;
UPDATE customers&lt;br&gt;
SET county = 'Nakuru';&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Because there is no `WHERE` condition, SQL will attempt to change the county to `Nakuru` for **every row in the table**.

Therefore, before executing an `UPDATE`, always check whether your `WHERE` condition identifies the intended records.

You can even check the affected records first:



```sql id="4ppfl4"
SELECT *
FROM customers
WHERE customer_id = 4;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Once you are satisfied that the correct record has been identified, you can execute the &lt;code&gt;UPDATE&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  3. DELETE — Removing Data
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;DELETE&lt;/code&gt; statement removes existing records from a table.&lt;/p&gt;

&lt;p&gt;Its basic syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="rfdjhu"&lt;br&gt;
DELETE FROM table_name&lt;br&gt;
WHERE condition;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


For example, suppose we want to remove the customer whose ID is `4`:



```sql id="97gexx"
DELETE FROM customers
WHERE customer_id = 4;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;WHERE&lt;/code&gt; condition tells the database exactly which record should be removed.&lt;/p&gt;

&lt;p&gt;As with &lt;code&gt;UPDATE&lt;/code&gt;, you must be careful when using &lt;code&gt;DELETE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Consider:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="b1f44m"&lt;br&gt;
DELETE FROM customers;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


Without a `WHERE` clause, this statement targets **all rows in the table**.

The table itself still exists, but its records will be removed.

This is different from:



```sql id="c68daw"
DROP TABLE customers;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;DROP TABLE&lt;/code&gt; removes the table itself, including its structure, whereas &lt;code&gt;DELETE&lt;/code&gt; removes records from an existing table.&lt;/p&gt;


&lt;h3&gt;
  
  
  4. SELECT — Retrieving Data
&lt;/h3&gt;

&lt;p&gt;Although &lt;code&gt;SELECT&lt;/code&gt; does not change the data stored in a table, it is one of the SQL commands you will use most frequently.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;SELECT&lt;/code&gt; is used to retrieve information from a database.&lt;/p&gt;

&lt;p&gt;To retrieve every column from the &lt;code&gt;customers&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="syf0pz"&lt;br&gt;
SELECT *&lt;br&gt;
FROM customers;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


The `*` means **all columns**.

If we only need customer names and counties, we can specify those columns:



```sql id="xy7fyq"
SELECT customer_name, county
FROM customers;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;We can also use &lt;code&gt;WHERE&lt;/code&gt; to retrieve only records matching a particular condition:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="rd3jgg"&lt;br&gt;
SELECT customer_name, county&lt;br&gt;
FROM customers&lt;br&gt;
WHERE county = 'Nairobi';&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


This asks the database to return customers whose county is Nairobi.

`SELECT` becomes much more powerful when combined with SQL features such as:

* `WHERE` for filtering
* `ORDER BY` for sorting
* `GROUP BY` for grouping
* Aggregate functions such as `SUM()`, `COUNT()`, `AVG()`, `MIN()`, and `MAX()`
* `JOIN` for retrieving related information from multiple tables

These concepts can be explored separately as you progress beyond basic DML.

---

## Bringing the DML Commands Together

We can think about the commands in terms of the lifecycle of a record.

A record is first **created**:



```sql id="j18qnd"
INSERT INTO customers (customer_name, county, email)
VALUES ('Alice Njeri', 'Nairobi', 'alice@example.com');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It can later be &lt;strong&gt;read&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="os2xvw"&lt;br&gt;
SELECT *&lt;br&gt;
FROM customers&lt;br&gt;
WHERE customer_name = 'Alice Njeri';&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


If something changes, it can be **updated**:



```sql id="c39tn2"
UPDATE customers
SET county = 'Nakuru'
WHERE customer_name = 'Alice Njeri';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally, if the record is no longer required, it can be &lt;strong&gt;deleted&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;```sql id="vz7ij9"&lt;br&gt;
DELETE FROM customers&lt;br&gt;
WHERE customer_name = 'Alice Njeri';&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


These four operations are often described using the acronym **CRUD**:

| CRUD Operation | SQL Command | Purpose                |
| -------------- | ----------- | ---------------------- |
| Create         | `INSERT`    | Add new data           |
| Read           | `SELECT`    | Retrieve existing data |
| Update         | `UPDATE`    | Modify existing data   |
| Delete         | `DELETE`    | Remove existing data   |

CRUD operations form the foundation of how many applications interact with relational databases.

For example, when a customer creates an account on an online platform, the application may use an `INSERT` operation behind the scenes. When the customer views their profile, the application retrieves their information. Updating their address modifies the existing record, while deleting an account may involve removing or deactivating the associated data.

Understanding DML therefore goes beyond learning SQL syntax. It helps us understand how applications create, retrieve, modify, and manage the data that organizations use every day.

##Conclusion

Understanding DDL (Data Definition Language) and DML (Data Manipulation Language) is an important foundation for anyone learning SQL and relational databases.

DDL focuses on the structure of the database. Commands such as CREATE, ALTER, TRUNCATE, and DROP allow us to create and manage database objects such as tables.

DML, on the other hand, focuses on the data stored within those structures. Commands such as INSERT, UPDATE, and DELETE allow us to add, modify, and remove records, while SELECT is commonly used to retrieve and explore the stored data.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>database</category>
      <category>beginners</category>
      <category>learning</category>
      <category>writing</category>
    </item>
    <item>
      <title>DIVING DEEPER INTO POWER BI</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Wed, 16 Sep 2026 23:58:27 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/diving-deeper-into-power-bi-ih3</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/diving-deeper-into-power-bi-ih3</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’ve ever packed a backpack for a long trip, you know that just throwing everything into one giant pocket makes a total mess. When you urgently need your passport, you have to dig past tangled headphones, loose change, and extra clothes. Power BI is no different. If you dump all your data into one big, messy spreadsheet, your reports will break and run painfully slow. Mastering Power BI is simply the art of packing your data into the right compartments so that finding answers is instant and effortless.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Power BI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Power BI is a &lt;em&gt;Microsoft's business analytics and data visualization platform&lt;/em&gt;. It lets you &lt;em&gt;connect to various data sources&lt;/em&gt;, &lt;em&gt;clean and transform raw information, and build interactive dashboards&lt;/em&gt; that reveal trends and track Key Performance Indicators (KPIs) to drive better business decisions.&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%2Fkw6qjux6jfvzk3ei9kh0.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkw6qjux6jfvzk3ei9kh0.JPG" alt="bi intro" width="799" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the definition, we can say that the Power BI has four main functionalities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Connect&lt;/em&gt; -Power BI enables one to intergrate data from various sources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Transform&lt;/em&gt; - This utilises tools like Power Query and is useful in cleaning, merging and working on raw data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Model&lt;/em&gt;- Power BI enables creating relationship within a dataset to enable easy analysis.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Visualize&lt;/em&gt; - Finaly, you can use the models created to visualize data in a dashboard and draw conclusions that can be used to make business decisions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Power BI provides a complete platform for collecting, transforming, modelling, analyzing, and visualizing data. To fully utilize its capabilities, it is important to understand the key concepts that form the foundation of Power BI.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Areas to be covered&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The foundation : Data Ingestion and Transformation (Power Query)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fact vs. Dimension Tables: Organizing Your Pantry&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Blueprint: Data Modelling and Schema Design&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Glue : Joins vs Relationships&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Engine : The DAX Calculation layer&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The Presentation : Visualizations and Reporting&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this section, we will dive deeper into what Power BI is and explore the fundamental concepts that will help us build efficient data models and create impactful analytical reports.&lt;/p&gt;

&lt;h2&gt;
  
  
  The foundation : Data Ingestion and Transformation (Power Query)
&lt;/h2&gt;

&lt;p&gt;Before you can cook a magnificent, five-star meal, you have to spend some time in the kitchen prepping your ingredients. You would never throw an unpeeled onion, unwashed vegetables, and raw chicken straight into a pot together. If you did, the final dish would be a complete disaster. You have to wash, chop, peel, and sort your ingredients first.&lt;/p&gt;

&lt;p&gt;In Power BI, this digital kitchen is called Power Query, and it is where you perform ETL (Extract, Transform, Load).&lt;/p&gt;

&lt;p&gt;When you import raw data into Power BI from Excel spreadsheets or databases, it arrives messy. It often contains typos, missing information, blank rows, and poorly formatted dates. Power Query acts as your data preparation room. Without writing any complicated code, you can click simple buttons to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Chop away excess data&lt;/strong&gt;: Remove columns and rows you don’t need.&lt;br&gt;
&lt;strong&gt;Wash the data&lt;/strong&gt;: Fix typos, replace errors, and filter out blank spaces.&lt;br&gt;
&lt;strong&gt;Organize the pantry&lt;/strong&gt;: Ensure numbers are treated as numbers and dates look like actual calendar dates.&lt;/p&gt;

&lt;p&gt;By taking the time to cleanly prepare your data "ingredients" in Power Query first, you ensure that the rest of your Power BI building experience is fast, smooth, and error-free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fact vs. Dimension Tables: Organizing Your Pantry
&lt;/h2&gt;

&lt;p&gt;Now that your data ingredients are clean and prepped, it’s time to organize them. In Power BI, you don't just dump all your data into one massive, endless spreadsheet. Instead, you separate your data into two distinct types of tables: &lt;strong&gt;Fact tables&lt;/strong&gt; and &lt;strong&gt;Dimension tables&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To a complete beginner, these names sound intimidating, but they are just like dividing your kitchen into a Sales Ledger and a Pantry.&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%2Fqc9cwahevylhk636h36o.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqc9cwahevylhk636h36o.JPG" alt="fact table and dimension table" width="800" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Fact TAbles (The "Sales Ledger)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Think of the Fact table as a fast-moving restaurant's sales ledger. Every single time a customer buys a meal, a new line is written down. It answers the questions “&lt;em&gt;How much?&lt;/em&gt;”, “&lt;em&gt;How many?&lt;/em&gt;”, and “&lt;em&gt;When?&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What lives here:&lt;/strong&gt; Numbers, quantities, and prices (metrics). It also holds unique ID numbers to link back to your pantry.&lt;br&gt;
&lt;strong&gt;The Shape:&lt;/strong&gt; It is a narrow but incredibly deep table. It might only have a few columns, but it can easily hold millions of rows recording every single historical transaction.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Dimension Tables (The "Pantry Items")&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Think of Dimension tables as the labeled jars sitting neatly in your pantry. They don't record actions; instead, they hold the descriptive details about the things surrounding the actions. They answer the questions “&lt;em&gt;Who?&lt;/em&gt;”, “&lt;em&gt;What?&lt;/em&gt;”, and “&lt;em&gt;Where?&lt;/em&gt;”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What lives here:&lt;/strong&gt; Text labels like product names, food categories, customer addresses, store locations, and calendar dates.&lt;br&gt;
&lt;strong&gt;The Shape:&lt;/strong&gt; It is a _wide but shallow _table. It has lots of descriptive columns (like item color, size, and category) but far fewer rows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Separate Them?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you wrote the full name, address, and phone number of a customer on every single line of your sales ledger, your book would become massive, bloated, and impossible to read. By keeping the details in the pantry (Dimension tables) and the math in the ledger (Fact table), Power BI can find answers in milliseconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Blueprint: Data Modelling and Schema Design
&lt;/h2&gt;

&lt;p&gt;Now that you have separated your clean ingredients into a transactional ledger (Fact table) and structured pantry jars (Dimension tables), you need a plan for how they will sit together. In the tech world, this layout plan is called &lt;strong&gt;Schema Design&lt;/strong&gt;, and the act of connecting them is called &lt;strong&gt;Data Modeling&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think of this as designing the physical blueprint and traffic flow of your kitchen so the chef can grab ingredients instantly without tripping over anything.&lt;/p&gt;

&lt;p&gt;In Power BI, there is one supreme blueprint that beats all others: &lt;strong&gt;The Star Schema.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is a Star Schema?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Star Schema is simply a visual pattern.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Center:&lt;/strong&gt; You place your heavy Fact table (the sales ledger) right in the middle of your digital workspace.&lt;br&gt;
&lt;strong&gt;The Points:&lt;/strong&gt; You place your Dimension tables (the pantry jars for Products, Customers, and Dates) in a ring surrounding that central table.&lt;/p&gt;

&lt;p&gt;When you draw connection lines from each surrounding pantry jar to the central ledger, the layout naturally begins to look like a &lt;strong&gt;star&lt;/strong&gt; (or a solar system with planets orbiting a central sun).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why is this blueprint the "Golden Rule"?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Power BI is custom-engineered from the ground up to read data that is laid out like a star. When a user clicks a button on your dashboard to filter by "October" or "Espresso Drinks," Power BI starts at the outer edge of the star (the Dimension table) and flows smoothly down a single highway directly into the center (the Fact table) to calculate the totals.&lt;/p&gt;

&lt;p&gt;If you don't follow this blueprint—and instead create a chaotic spiderweb of tangled tables—your report will become painfully slow, your charts will show incorrect numbers, and your calculations will break.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Glue: Joins vs. Relationships
&lt;/h2&gt;

&lt;p&gt;Now that you have your Star Schema blueprint mapped out on paper, you need to actually connect your tables so they can talk to each other. In Power BI, this is where beginners often get tripped up because they hear two terms used interchangeably: &lt;strong&gt;Joins **and **Relationships&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;While both act as the "glue" that connects your data using a matching ID column (like a ProductID), they happen at entirely different times and serve completely different purposes.&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%2Foldwt8t5dzfzywb0921t.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%2Foldwt8t5dzfzywb0921t.png" alt="JOINS" width="710" height="684"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Joins (The Upstream Glue)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A Join happens early in the kitchen prep room &lt;strong&gt;(Power Query)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; Imagine taking two separate pieces of paper—like a list of subcategories and a list of categories—and physically smashing them together with glue to create one single, wider spreadsheet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Goal:&lt;/strong&gt; You use Joins to clean up messy data layouts (like a snowflake schema) and flatten them down so they fit perfectly into your neat outer pantry jars (Dimension tables).&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Relationships (The Downstream Glue)&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A Relationship happens later on the main stage (&lt;strong&gt;Model View canvas&lt;/strong&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How it works:&lt;/strong&gt; Instead of physically smashing tables together, a relationship keeps the tables completely separate but cuts a "peek-a-boo window" or draws a bridge between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Goal:&lt;/strong&gt; You draw virtual connection lines directly from your outer pantry jars to your central ledger. This tells Power BI: "When a user filters a chart by a specific product name over here, look across the bridge and update the total sales numbers over there."&lt;/p&gt;

&lt;h3&gt;
  
  
  Why the Difference Matters to You
&lt;/h3&gt;

&lt;p&gt;If you use Joins for everything, your data model becomes one giant, bloated spreadsheet that slows Power BI to a crawl. If you use Relationships correctly to connect your Star Schema, your file size stays incredibly small, and your reports run lightning-fast.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Engine: The DAX Calculation Layer.
&lt;/h2&gt;

&lt;p&gt;Once your tables are neatly prepped, organized into a star layout, and connected by relationships, your data is officially ready to work for you. But how do you actually calculate your business metrics, like your total profit margins, year-over-year growth, or active customer counts?&lt;/p&gt;

&lt;p&gt;You use *&lt;em&gt;DAX *&lt;/em&gt;(Data Analysis Expressions).&lt;/p&gt;

&lt;p&gt;Think of DAX as the high-powered engine under the hood of Power BI. While it looks a bit like Excel formulas, it behaves completely differently. For a beginner, the absolute most important step to mastering DAX is understanding the difference between a &lt;strong&gt;Calculated Column&lt;/strong&gt; and a &lt;strong&gt;Measure&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Calculated Columns (The Hard Drive Glues)
&lt;/h3&gt;

&lt;p&gt;A Calculated Column calculates a new value for every single row in your table, right when the data is loaded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Analogy:&lt;/strong&gt; Imagine writing a new number by hand onto every single receipt line in your ledger.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Cost:&lt;/strong&gt; Because these numbers are physically written into your data, they take up permanent storage space. If you have millions of rows, your file size will balloon quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use:&lt;/strong&gt; Use them sparingly, usually only when you need to create a new text label for a slicer or filter (like grouping ages into "Under 30" and "30+").&lt;/p&gt;

&lt;h3&gt;
  
  
  Measures (The On-Demand Calculator)
&lt;/h3&gt;

&lt;p&gt;A Measure does not calculate anything ahead of time and takes up zero physical storage space. It sits completely invisible in your model until you drop it onto a chart.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Analogy:&lt;/strong&gt; Think of a measure like a programmable button on a smart calculator. It waits patiently until you click it, instantly looks at whatever filters are currently active on your dashboard screen, and calculates the answer on the fly in milliseconds.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Benefit:&lt;/strong&gt; It keeps your Power BI files incredibly small and handles dynamic filtering seamlessly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use:&lt;/strong&gt; Use measures for 99% of your math—sums, averages, percentages, and performance metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Golden Concept: Filter Context
&lt;/h3&gt;

&lt;p&gt;As a beginner, you will hear the phrase "Filter Context" a lot. Don't let it scare you. It simply means that &lt;strong&gt;DAX measures adapt to their environment&lt;/strong&gt;. If you drop a "Total Sales" measure into a bar chart showing different countries, that single measure instantly figures out how to calculate Sales for Canada in the Canada bar, and Sales for Kenya in the Kenya bar. It only calculates what the user is currently looking at.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Presentation: Visualizations &amp;amp; Reporting
&lt;/h2&gt;

&lt;p&gt;You have prepped your ingredients in Power Query, organized your kitchen into a Star Schema, connected the tables with relationships, and built your DAX calculation engine. Now comes the fun part: serving the meal to your guests. In Power BI, this is the &lt;strong&gt;Visualization and Reporting layer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This is where the magic happens for the person reading your report, but as a creator, you must understand how your back-end structure controls your front-end visuals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visuals are Just Windows into Your Data
&lt;/h3&gt;

&lt;p&gt;Every chart, graph, map, and card you drop onto your canvas is just a visual window running your DAX calculations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Golden Rule for Layouts:&lt;/strong&gt; When building a visual, you will almost always pull your text categories and labels (like Product Name, Region, or Month) from your &lt;strong&gt;Dimension tables&lt;/strong&gt; to use as your chart axes, rows, or slicers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Golden Rule for Numbers:&lt;/strong&gt; You will always pull your dynamic &lt;strong&gt;Measures&lt;/strong&gt; (like Total Revenue or Profit Margin) into the values field of the chart.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Interaction Works: Filter Propagation
&lt;/h3&gt;

&lt;p&gt;The coolest feature of Power BI for a beginner is interactivity—click on a slice of a pie chart, and the rest of the page instantly updates. This is called &lt;strong&gt;Filter Propagation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Because you drew those neat "relationship bridges" earlier in your Star Schema, clicking a visual sends a silent command across the bridge. It instantly filters down your tables behind the scenes, and your DAX measures recalculate the new numbers in the blink of an eye.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep It Simple for Your User
&lt;/h3&gt;

&lt;p&gt;When designing the actual report page, remember that your audience didn't see all the hard work you did behind the scenes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Don't clutter the page with dozens of complex charts just because you can.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stick to 3 or 4 key visuals per page.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure your most critical number (like total profit) stands out in a large, easy-to-read "Card" visual right at the top.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion: Your Data Masterpiece Awaits
&lt;/h2&gt;

&lt;p&gt;Building a Power BI report doesn't have to feel like a mystery. By understanding these core concepts, you have shifted from someone who just clicks random buttons to a true data architect.&lt;/p&gt;

&lt;p&gt;Remember the journey your data takes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Power Query cleans and preps your raw ingredients.&lt;/li&gt;
&lt;li&gt;The Star Schema organizes them into a central Fact table surrounded by detailed Dimension tables.&lt;/li&gt;
&lt;li&gt;Relationships build the bridges that let your tables talk to each other.&lt;/li&gt;
&lt;li&gt;DAX Measures act as the smart, on-demand calculators.&lt;/li&gt;
&lt;li&gt;Visualizations bring it all to life for your audience.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Now, It’s Your Turn!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The absolute best way to master Power BI is to get your hands dirty. Open up Power BI Desktop, pull in a simple spreadsheet, and start sorting your ingredients. Don't worry about making it perfect on your first try—every expert dashboard designer started exactly where you are sitting right now. Trust your blueprint, lean into the process, and go build your very first data masterpiece!&lt;/p&gt;

</description>
      <category>data</category>
      <category>learning</category>
      <category>software</category>
      <category>tooling</category>
    </item>
    <item>
      <title>Connecting Power BI to SQL databases : Local PostgreSQL and Aiven cloud</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Tue, 15 Sep 2026 16:54:13 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/connecting-power-bi-to-sql-databases-local-postgresql-and-aiven-cloud-25ll</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/connecting-power-bi-to-sql-databases-local-postgresql-and-aiven-cloud-25ll</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Power BI supports connectivity to a wide range of data sources. This includes &lt;em&gt;files, relational databases, cloud platforms, web services and online applications&lt;/em&gt;. In this article, we will focus specifically on connecting Power BI to PostgreSQL database. This can be done either locally or using the cloud.&lt;br&gt;
A &lt;strong&gt;Database&lt;/strong&gt; is is a highly organized, centralized digital system designed to store, manage, secure, and instantly retrieve massive amounts of structured data.&lt;br&gt;
A database is managed by a software engine as known as the &lt;strong&gt;database management system (DBMS)&lt;/strong&gt;, like SQL Server or PostgreSQL. When Power BI asks for data, this engine does the heavy lifting: filtering, aggregating, and sorting millions of rows in milliseconds before sending just the necessary results back to Power BI.&lt;br&gt;
We will explore two scenarios: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Connecting Power BI to a postgreSQL database hosted locally.&lt;/li&gt;
&lt;li&gt;Connecting Power BI to a cloud-hosted postgreSQL database using Aiven with SSL configuraion &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before proceeding, it will be important to compare the two scenarios:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tbody&gt;
&lt;tr&gt;
    &lt;th&gt;Attribute&lt;/th&gt;
    &lt;th&gt;Local PostgreSQL&lt;/th&gt;
    &lt;th&gt;Cloud-Hosted PostgreSQL&lt;/th&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Primary Location&lt;/td&gt;
    &lt;td&gt;Host machine (localhost or local IP)&lt;/td&gt;
    &lt;td&gt;Public cloud server instance&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt; 
  &lt;td&gt;Security Setup&lt;/td&gt;
  &lt;td&gt;Minimal setup; generally unencrypted over local networks&lt;/td&gt;
  &lt;td&gt;Strict Aiven Console CA certificate download and SSL configuration (sslmode=require)&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt; 
  &lt;td&gt;Accessibility&lt;/td&gt;
  &lt;td&gt;Limited to the local device or a restricted local network&lt;/td&gt;
  &lt;td&gt;Accessible anywhere over the internet&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt; 
  &lt;td&gt;Maintenance&lt;/td&gt;
  &lt;td&gt;User-managed (manual updates, scaling, backups)&lt;/td&gt;
  &lt;td&gt;Fully managed by Aiven (automated patches, easy hardware scaling)&lt;/td&gt;
  &lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Connecting Power BI to a local SQL database
&lt;/h2&gt;

&lt;p&gt;A local database is a database server installed and run entirely on your own local computer rather than a remote cloud or external server.&lt;/p&gt;

&lt;h3&gt;
  
  
  Process 1: Connecting  a new localhost database in DBeaver.
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;&lt;br&gt;
To get started with the process, we need to download all the tools that we need for the process. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The postgreSQL from our browser. Clink this link to download from the official site, &lt;a href="https://www.postgresql.org/download/" rel="noopener noreferrer"&gt;PostgreSQL download link&lt;/a&gt;.
We then install it to our computer.&lt;/li&gt;
&lt;li&gt;DBeaver which is a free, open-source database management tool recommended for personal projects. Used to manage and explore SQL databases like MySQL, MariaDB, PostgreSQL, SQLite, Apache Family, and more. We will download and install it in our local machine.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;&lt;br&gt;
We then open the DBeaver and create a new local database connection with PostgreSQL Database.&lt;br&gt;
When you open the debeaver, a the Home screen will open as shown  below will open:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flixvupg5huh2vvf8jmtn.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flixvupg5huh2vvf8jmtn.JPG" alt="DBeaver home layout" width="799" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create a new database connection, we will press the CTRL + SHIFT + N  open or alternatively we can click the new connection wizard button &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%2Fyl12e4rzx3r7vzmqtfus.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%2Fyl12e4rzx3r7vzmqtfus.png" alt="new connection button" width="20" height="20"&gt;&lt;/a&gt; in the toolbar. This will open a new window as shown below.&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%2F70t90s9kucdzu2w241iv.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%2F70t90s9kucdzu2w241iv.png" alt="create a databse window" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;&lt;br&gt;
We will then click on the postgreSQL icon and it will take us to a new window to configure the connection. Since we are using localhost, we will not be required to change the configurations. We only need to input our password which we had set while installing our postgreSQL database.&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%2F17wb4rksdbe7o8p0dkkh.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%2F17wb4rksdbe7o8p0dkkh.png" alt="connection configuration" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;&lt;br&gt;
After inputing our password, we will be required to test our connection by pressing the test connection button in the bottom left conner of the window pane. If the connection is sucessful, we will the press the finish button in the bottom right conner to complete the process.&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%2Fnh416vpkirrq6nuf8ad8.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%2Fnh416vpkirrq6nuf8ad8.png" alt="Test connection and finish" width="800" height="586"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;&lt;br&gt;
In the home screen of DBeaver, a section will appear that will show our new connection as shown below.&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%2F8817f326cmg4mwyat43w.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%2F8817f326cmg4mwyat43w.png" alt="Connection established" width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Process 2: Importing data to our database
&lt;/h3&gt;

&lt;p&gt;After confirming that we already have our database connection working in DBeaver, we will need to import data to our database.&lt;br&gt;
This is an important step that we will need in the later stages.&lt;/p&gt;

&lt;p&gt;To import data to DBeaver, on the left side expand on databases &amp;gt; defaultdb &amp;gt; schemas &amp;gt; either create a new schema or use the public schema.&lt;br&gt;
We will first create a databse schema where now we will be able to put our data.&lt;br&gt;
To create a schema we will use the sql command: &lt;br&gt;
&lt;strong&gt;create schema schemaName;&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Inside our schema, we will import our data from the browser.&lt;br&gt;
&lt;em&gt;Right click on your preffered schema and click import data&lt;/em&gt;.A window will po up as shown below.&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%2Fxgt2jmqfj45bwh7bvone.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%2Fxgt2jmqfj45bwh7bvone.png" alt="dbeaver data import" width="799" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to -&amp;gt; Input file(s), Browse and select your data&lt;/p&gt;

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

&lt;p&gt;After selecting the file to be imported, you will click next until the end where you you will click proceed. This will complete the process of importation. Congratulations, you will now have completed the process of data importation. Your data will appear as shown below;&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%2F74z80f87wv84mipbb90v.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%2F74z80f87wv84mipbb90v.png" alt="data importation complete" width="799" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Process 3: Getting data in power BI
&lt;/h3&gt;

&lt;p&gt;We will now open our Power BI desktop app, we will click on the blank remote to work with it.&lt;/p&gt;

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

&lt;p&gt;Expand the view in the Get data section as shown below.&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%2F9slsfgjgjhqbogbk6avg.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%2F9slsfgjgjhqbogbk6avg.png" alt="get data source" width="751" height="739"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;more...&lt;/strong&gt; to expand our options to open a dialog box.&lt;br&gt;
In the dialog box, search for &lt;strong&gt;PostgreSQL&lt;/strong&gt; database under the Database category and click &lt;strong&gt;Connect&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;After clicking connect, a dialog box will appear that will require our server and database name. We get this information from the time we connected our PostgreSQL database in DBeaver.&lt;br&gt;
Server: &lt;strong&gt;localhost:5432  / 127.0.0.1 : 5432&lt;/strong&gt; . &lt;br&gt;
(&lt;em&gt;Note: 5432 is our port number.&lt;/em&gt;)&lt;br&gt;
Database: &lt;strong&gt;postgres&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After imputing the values, we proceed by clicking the &lt;strong&gt;ok buttton&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;A new dialog box will appear that requires our User name and password.&lt;br&gt;
User name: &lt;strong&gt;postgres&lt;/strong&gt;&lt;br&gt;
Password: **** (requires the password you set while installing PostgreSql.)&lt;br&gt;
Proceed by clicking the button &lt;strong&gt;connect&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;This wil take us to a new window where we can access all the tables we had already imported in DBeaver. Choose the tables you want to work on. if you need to clean you can using the &lt;strong&gt;transform&lt;/strong&gt; button which will direct you into power query where you will be able to clean your data. Otherwise, you can &lt;strong&gt;load&lt;/strong&gt; the tables directly so you can start working on them.&lt;/p&gt;

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

&lt;p&gt;Congratulations you have successfully connected Power BI to your localhost postgreSQL database!&lt;/p&gt;

&lt;p&gt;Let's now look into how you can connect to a cloud based &lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting Power BI to a cloud-hosted postgreSQL database using Aiven with SSL configuraion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;STEP 1: Setting up our aiven account.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Aiven.&lt;/strong&gt;&lt;br&gt;
Aiven is a fully managed cloud data platform that provides open-source technologies, such as PostgreSQL and Apache Kafka, as a service. It automates complex infrastructure tasks like setup, security patching, backups, and scaling so developers can focus strictly on building applications. The platform allows you to deploy these managed databases seamlessly across major cloud environments, including AWS, Google Cloud, and Microsoft Azure. By offering an accessible free tier, it makes it easy for developers to launch and manage a PostgreSQL database globally with minimal effort.&lt;/p&gt;

&lt;p&gt;To setup our aiven account,we will need to go to our browser an type &lt;a href="https://aiven.io/" rel="noopener noreferrer"&gt;aiven.io&lt;/a&gt;&lt;br&gt;
 When aiven.io opens, click on &lt;strong&gt;get building&lt;/strong&gt; to proceed to set up our aiven account.&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%2Fbmpmg0i32oamudwrv5nb.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%2Fbmpmg0i32oamudwrv5nb.png" alt="aiven home" width="799" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will need to sign up into your account and then you login  to your account. You will be taken to a window that will require you to create a service.&lt;br&gt;
Choose &lt;strong&gt;PostgreSQL as your service&lt;/strong&gt; and click the &lt;strong&gt;create service&lt;/strong&gt; buttom in the bottom right of the window.&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%2Fnowh938qttpvty9kwzh7.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fnowh938qttpvty9kwzh7.JPG" alt="aiven console" width="799" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will be taken into the projects tabs where we can see our service details. This details are important to help us later when we open Power BI.&lt;br&gt;
&lt;strong&gt;Note&lt;/strong&gt;: Make sure the services builds until you see it's status changes to &lt;strong&gt;running&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;STEP 2: Connecting our database in DBeaver.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To establish a cloud database connection in dbeaver, we will start by opening dbeaver console.&lt;/p&gt;

&lt;p&gt;Using the &lt;strong&gt;new connection button&lt;/strong&gt; or the shortcut &lt;strong&gt;SHIFT + CTRL + N&lt;/strong&gt; to establish a open a dialog window.&lt;br&gt;
In the dialog box, choose &lt;strong&gt;postgreSQL&lt;/strong&gt; as our database and click &lt;strong&gt;next&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Next, we configure the database based on the details we generated from the service we created in aiven.io&lt;/p&gt;

&lt;p&gt;Host: &lt;em&gt;according to the service you created in aiven.&lt;/em&gt;&lt;br&gt;
Port: &lt;em&gt;according to the service you created in aiven.&lt;/em&gt;&lt;br&gt;
Database: &lt;em&gt;defaultdb&lt;/em&gt;&lt;br&gt;
Username: &lt;em&gt;avnadmin&lt;/em&gt;&lt;br&gt;
Password: &lt;em&gt;according to the service you created in aiven.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Test the connection by clicking on the button &lt;strong&gt;Test connection&lt;/strong&gt; in the bottom left corner then click &lt;strong&gt;finish&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;After finishing the action, you will be able to see a new connection in the General tab under connections.&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%2F76nc5ti73p7ot244b5bw.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F76nc5ti73p7ot244b5bw.JPG" alt="general connection" width="622" height="582"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 43: CA cerificate download and Importation into our Trusted root crtificates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The proceed without doing this step we will generate this error.&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%2Fkx6wzbchn5pqpxgjl2lm.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkx6wzbchn5pqpxgjl2lm.JPG" alt="ca error" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need the Aiven PostgreSQL Service Certificate because Aiven enforces strict, mandatory SSL/TLS encryption for all database connections by default, and your computer needs to trust Aiven's identity to establish a secure link.&lt;br&gt;
Therefore we will need to download and import the CA certificate into our trusted root certifications. &lt;/p&gt;

&lt;p&gt;To proceed we will download the CA certificate in aiven.io.&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%2Ffhcuow5dxw2y9dz9pq47.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%2Ffhcuow5dxw2y9dz9pq47.png" alt="va cert download" width="800" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After dowloading the CA certificate, we will need to import the certifictae to our managed user certificates.&lt;/p&gt;

&lt;p&gt;Open the &lt;strong&gt;managed user certificate control panel&lt;/strong&gt; in your computer, and under the &lt;strong&gt;Trusted root certification&lt;/strong&gt;, &lt;strong&gt;right click on certificates , under all tasks click on import&lt;/strong&gt;, click &lt;strong&gt;next&lt;/strong&gt; then &lt;strong&gt;browse&lt;/strong&gt; the VA certificte you downloaded and proceed until you click the &lt;strong&gt;finish button&lt;/strong&gt;. &lt;/p&gt;

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

&lt;p&gt;To confirm if the process is successful, a success message box will appear.&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%2Fhjusmzua64oyz8vlesje.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%2Fhjusmzua64oyz8vlesje.png" alt="va import success" width="417" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;STEP 4: Connecting PowerBI to our aiven PostgreSQL database.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will now open our Power BI Desktop App, we will click on the &lt;strong&gt;blank report&lt;/strong&gt; to work with it.&lt;/p&gt;

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

&lt;p&gt;Expand the view in the **Get data **section as shown below.&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%2F9slsfgjgjhqbogbk6avg.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%2F9slsfgjgjhqbogbk6avg.png" alt="get data source" width="751" height="739"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;more...&lt;/strong&gt; to expand our options to open a dialog box.&lt;br&gt;
In the dialog box, search for &lt;strong&gt;PostgreSQL&lt;/strong&gt; database under the Database category and click &lt;strong&gt;Connect&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;A dialog box will appear that will require us to input the server and Database box with values that we obtain while creating the service in aiven.io.&lt;br&gt;
Server: &lt;strong&gt;Host name : port number&lt;/strong&gt; (Depending on your service)&lt;br&gt;
Database: &lt;strong&gt;defaultdb&lt;/strong&gt;&lt;br&gt;
Press &lt;strong&gt;ok&lt;/strong&gt; to proceed.&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%2F1nebbeb3375jtjxmtvw6.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%2F1nebbeb3375jtjxmtvw6.png" alt="server and database" width="799" height="585"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A new dialog box will appear that will require our username and password. Refer to our service conection details in aiven.ai.&lt;br&gt;
Username: &lt;strong&gt;avnadmin&lt;/strong&gt;&lt;br&gt;
Password: (&lt;em&gt;as provided in the service you created&lt;/em&gt;)&lt;br&gt;
Click &lt;strong&gt;connect&lt;/strong&gt; to to proceed&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%2F9f1t83npkfxbaqzrdlb4.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%2F9f1t83npkfxbaqzrdlb4.png" alt="bi aiven" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This will take us to a new window where we can access all the tables we had already imported in DBeaver. Choose the tables you want to work on. if you need to clean you can using the &lt;strong&gt;transform&lt;/strong&gt; button which will direct you into power query where you will be able to clean your data. Otherwise, you can &lt;strong&gt;load&lt;/strong&gt; the tables directly so you can start working on them.&lt;/p&gt;

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

&lt;p&gt;Congratulations you have successfully connected Power BI to your aiven postgreSQL database!&lt;/p&gt;

&lt;p&gt;Hope you enjoyed this blog. Until next time.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>database</category>
      <category>learning</category>
      <category>data</category>
    </item>
    <item>
      <title>HOW EXCEL IS USED IN REAL WORLD DATA ANALYSIS</title>
      <dc:creator>Gideon Kiprono</dc:creator>
      <pubDate>Sat, 06 Jun 2026 21:14:21 +0000</pubDate>
      <link>https://dev.to/gideon_kiprono_bfdedde010/how-excel-is-used-in-real-world-data-analysis-ef2</link>
      <guid>https://dev.to/gideon_kiprono_bfdedde010/how-excel-is-used-in-real-world-data-analysis-ef2</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is Excel
&lt;/h2&gt;

&lt;p&gt;Excel is an important tool used in Data analysis. Excel enables a data analyst to ineteract with raw data. Raw data are always messy and require cleaning. This is now the work of excel to help in cleaning, organizing, analysing and visualizing data. &lt;/p&gt;

&lt;h2&gt;
  
  
  Ways Excel is used in real world data analysis
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Financial Modelling&lt;/strong&gt; . Excel is used in building financial models that can be used to predict the performance of a business. Excel formulas can be used to calculate profits, revenue and costs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auditing&lt;/strong&gt;.Auditors use excel in analysing financial records of an organization.They use it to check errors, detect any fraud and verify financial records.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tasks Automation&lt;/strong&gt;. Excel can be used to automate repetitive tasks using formulas.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Data Visualization&lt;/strong&gt;. One can use excel to turn raw data into charts, graphs and dashboards for easier interpretation of the data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Basic featuers of Excel
&lt;/h2&gt;

&lt;p&gt;Excel as a tool has many features that enable it bto function properly, this includes;&lt;/p&gt;

&lt;h4&gt;
  
  
  Excel Ribbon
&lt;/h4&gt;

&lt;p&gt;The Excel Ribbon is the toolbar located at the top of the excel interface that contains all commands and tools organized into tabs such as Home, Insert, Data, Formulas and View. Each tab groups related functions for easy access.&lt;/p&gt;

&lt;h4&gt;
  
  
  Data Entry and Formatting
&lt;/h4&gt;

&lt;p&gt;Excel allows users to enter different kinds of data such as texts, numbers and dates. Formatting tools are also used for organizing data to improve readability.&lt;/p&gt;

&lt;h4&gt;
  
  
  Filtering and Sorting
&lt;/h4&gt;

&lt;p&gt;Filtering helps in displaying specific data, while sorting arranges data in ascending or descending order. They help to in organizing large datasets.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conditional Formating
&lt;/h4&gt;

&lt;p&gt;This is a special feature that helps in highlighting data based on specific rules, making it easier to identify trends and patterns.&lt;/p&gt;

&lt;h4&gt;
  
  
  Functions in Excel
&lt;/h4&gt;

&lt;p&gt;Excel has differnt kinds of functions that aid in data analysis;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Mathematical / Aggregate Functions&lt;/em&gt;: SUM(), AVERAGE(), MEDIAN(),MODE().&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Statistical Functions&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Text Functions&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Lookup Functions&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Date and time functions&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;I am not going to lie, Before doing a deep dive into how excel works, my understanding was that excel was not that powerful in data analysis. To my suprise, I have come to know and appreciate excel as a powerful tool in the hands of any aspiring analyst. &lt;/p&gt;

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