Light

🎓 Welcome to CSE Helper

Choose a course to start learning algorithms, data structures, and SQL

📚
CSE 220

Data Structures

Arrays, Stacks, Queues, Linked Lists, Trees, Heaps

0/6
CSE 221

Algorithms

Sorting, Pathfinding, Algorithm Analysis & Racing

0/4
🗄️
CSE 370

Database Systems

SQL Lab, Practice Challenges, Lessons & Visualizer

0/4
Compares 0
Swapping 0
Steps 0
● Sorted ● Compare ● Swap ● Pivot

⚡ Quick Sort

Quick Sort picks a "pivot" element and partitions the array into two sub-arrays: elements less than pivot vs. elements greater. It then recursively sorts the sub-arrays. Efficient and widely used!

Time Complexity

Best
O(n log n)
Avg
O(n log n)
Worst
O(n²)
function quickSort(arr, lo = 0, hi = arr.length - 1) {
if (lo < hi) {
  const pivot = arr[hi];
  let i = lo - 1;
  for (let j = lo; j < hi; j++) {
    if (arr[j] <= pivot) {
      i++;
      [arr[i], arr[j]] = [arr[j], arr[i]];
    }
  }
  [arr[i + 1], arr[hi]] = [arr[hi], arr[i + 1]];
  const p = i + 1;
  quickSort(arr, lo, p - 1);
  quickSort(arr, p + 1, hi);
}
return arr;
}
🔊 Sound
Sound Off
Volume 70%

📝 Your Code

IndexError Line ?
Array index out of bounds
Steps 0
Compares 0
Swaps 0

🫧 Bubble Sort

Like bubbles rising in water, larger elements "bubble up" to the end of the array. We repeatedly step through the list, compare adjacent elements, and swap them if they're in the wrong order.

Best Case
O(n)
Average
O(n²)
Worst Case
O(n²)

⚙️ Race Setup

20 elements

Merge Sort

Ready
Comparisons: 0 Swaps: 0 Time: 0ms

Bubble Sort

Ready
Comparisons: 0 Swaps: 0 Time: 0ms
Contiguous Memory
LOW -
MID -
HIGH -
Custom Array:
Target:
Implementation
Py Java C++

📖 The Library Story

You're in a library. A massive one. Your book is somewhere among 1,000 shelves...

The Slow Way (Linear Search): Check every single book. One by one. Starting from aisle one. You might be here all day—or all week.

The Smart Way (Binary Search): Books are alphabetized. Open to the middle—is your book before or after? Cut the remaining books in half. Repeat. 1,000 books? That's about 10 checks. A billion books? Only 30 checks. That's the power of logarithms.

🧠 Think First Challenge

Before we dive in, try this: You have a sorted list of 1 million numbers. How many comparisons would you need to find any number using:

Linear Search?

Binary Search?

📖 Reveal Answer

Linear: Up to 1,000,000 comparisons (worst case). Binary: Only ~20 comparisons! (log₂ of 1 million ≈ 20). That's why understanding algorithms matters.

📋 Linear Search

Check each element one by one until found. Works on any list.

Time
O(n)
Space
O(1)
Sorted?
No
Python
def linear_search(arr, target):
    for i in range(len(arr)):
        if arr[i] == target:
            return i  # Found!
    return -1  # Not found

⚡ Binary Search

Repeatedly divide the search space in half. Requires sorted array!

Time
O(log n)
Space
O(1)
Sorted?
Yes
Python
def binary_search(arr, target):
    left, right = 0, len(arr) - 1
    while left <= right:
        mid = (left + right) // 2
        if arr[mid] == target:
            return mid
        elif arr[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    return -1

🎯 When to Use What?

Scenario Best Choice Why
Unsorted small list Linear Search Sorting overhead not worth it
Sorted array, search once Binary Search O(log n) is much faster
Unsorted, many searches Sort first, then Binary O(n log n) sort + O(log n) × searches

🍕 The Pizza Problem

You've got a pizza the size of a table. How do you count every pepperoni? Don't stare at the whole thing—cut it in half. Count each half separately. Add them up.

Still too big? Cut again. Keep going until counting is easy. Then work backwards and combine your counts. That's Divide and Conquer: split → solve → combine.

If this feels like recursion, that's because it is. D&C and recursion are best friends.

🔑 The Three Steps

1️⃣
DIVIDE

Break problem into smaller subproblems

2️⃣
CONQUER

Solve subproblems recursively

3️⃣
COMBINE

Merge solutions together

🔀 Merge Sort (Classic D&C)

Divide array in half, sort each half, merge sorted halves.

Python
def merge_sort(arr):
    if len(arr) <= 1:
        return arr
    
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])   # Divide
    right = merge_sort(arr[mid:])  # Divide
    return merge(left, right)       # Combine

def merge(left, right):
    result = []
    i = j = 0
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1
    result.extend(left[i:])
    result.extend(right[j:])
    return result

⚡ Quick Sort

Pick pivot, partition around it, recursively sort partitions.

Python
def quick_sort(arr):
    if len(arr) <= 1:
        return arr
    
    pivot = arr[len(arr) // 2]
    left = [x for x in arr if x < pivot]
    middle = [x for x in arr if x == pivot]
    right = [x for x in arr if x > pivot]
    
    return quick_sort(left) + middle + quick_sort(right)
Best/Avg
O(n log n)
Worst
O(n²)

🔄 Recursion Fundamentals

A function that calls itself. Every recursive function needs TWO parts:

Base Case

The condition that STOPS recursion. Without it = infinite loop!

if n <= 1: return n
Recursive Case

The function calls itself with a SMALLER problem.

return n * factorial(n-1)
Pattern Description Example
Linear One recursive call per level factorial(n)
Binary Two recursive calls (tree shape) fibonacci(n)
Tail Return is the recursive call itself loop(n, acc)
Mutual A calls B, B calls A isEven/isOdd
Space (Stack)
O(depth)
Factorial
O(n)
Fib (naive)
O(2ⁿ)*

✂️ Interactive D&C Visualizer

Watch how the algorithm divides the array, conquers subproblems, and combines results step-by-step.

7
Step 0 / 0
def mergeSort(arr, l, r):
if l < r:
mid = (l + r) // 2
mergeSort(arr, l, mid) # DIVIDE left
mergeSort(arr, mid+1, r) # DIVIDE right
merge(arr, l, mid, r) # COMBINE
Click "Start" to begin the visualization. Use the playback controls to step through the algorithm.
Dividing
Base Case
Merging
Sorted

Click "Start" to visualize the algorithm

💻 Code Implementation

📚 Before you start: Make sure you understand recursion first. DP builds directly on recursive thinking.

🧠 Think First Challenge

Calculate fib(5) by hand. How many times do you calculate fib(2)?

fib(5) = fib(4) + fib(3)
fib(4) = fib(3) + fib(2)
fib(3) = fib(2) + fib(1)
...keep going...
📖 Reveal The Problem

You calculate fib(2) 3 times, fib(3) 2 times. This is the duplicate work DP eliminates. By storing results, each fib(n) is calculated only once. That's memoization.

🪜 The Staircase Problem

You're climbing a staircase with n steps. You can take 1 or 2 steps at a time. How many distinct ways can you reach the top?

The insight: To reach step n, you either came from step n-1 (took 1 step) or step n-2 (took 2 steps). So: ways(n) = ways(n-1) + ways(n-2). Wait—that's Fibonacci!

Once this clicks, you'll start seeing DP problems everywhere. It clicked for me on the third example.

🔄 Top-Down (Memoization)

Recursive approach with caching. "Remember what you've computed."

Python
def climb_stairs(n, memo={}):
    if n in memo:
        return memo[n]
    if n <= 2:
        return n
    
    memo[n] = climb_stairs(n-1, memo) + climb_stairs(n-2, memo)
    return memo[n]

# Without memo: O(2^n) - exponential!
# With memo: O(n) - linear!

📊 Bottom-Up (Tabulation)

Iterative approach building up from base cases. Often more efficient.

Python
def climb_stairs(n):
    if n <= 2:
        return n
    
    dp = [0] * (n + 1)
    dp[1] = 1
    dp[2] = 2
    
    for i in range(3, n + 1):
        dp[i] = dp[i-1] + dp[i-2]
    
    return dp[n]

# Time: O(n), Space: O(n)
# Can optimize to O(1) space!

🎒 Classic DP Problems

Problem Key Insight Complexity
Fibonacci F(n) = F(n-1) + F(n-2) O(n)
0/1 Knapsack Include item or skip it O(n × W)
Longest Common Subsequence Match chars or skip O(m × n)
Coin Change Min coins for each amount O(n × amount)

⚔️ Memoization vs Tabulation

Aspect Top-Down (Memo) Bottom-Up (Tab)
Approach Recursive + cache Iterative + table
Computes Only needed subproblems All subproblems
Stack Usage O(depth) - can overflow O(1) - no recursion
Best When Not all subproblems needed Need all / optimize space

💡 Interview tip: Start with memoization (easier to write), optimize to tabulation if needed!

🪙 The Coin Change Story

You're a cashier. Someone needs $0.63 in change. You want to use as few coins as possible. What do you do?

The greedy instinct: Grab the biggest coin that fits! Quarter (25¢) → Quarter (25¢) → Dime (10¢) → Penny → Penny → Penny = 6 coins. Pretty good!

⚠️ Plot twist: Greedy doesn't always win. With coins [1, 3, 4] for amount 6: greedy picks 4+1+1 = 3 coins. But 3+3 = 2 coins is better! Sometimes you need DP.

📅 Activity Selection

Given activities with start/end times, select max non-overlapping activities.

Python
def activity_selection(activities):
    # Sort by end time (greedy choice!)
    activities.sort(key=lambda x: x[1])
    
    selected = [activities[0]]
    last_end = activities[0][1]
    
    for start, end in activities[1:]:
        if start >= last_end:
            selected.append((start, end))
            last_end = end
    
    return selected

# Why it works: Earliest finish leaves
# most room for other activities!

🎒 Fractional Knapsack

Unlike 0/1 knapsack, you can take fractions of items.

Python
def fractional_knapsack(items, capacity):
    # Sort by value/weight ratio
    items.sort(key=lambda x: x[0]/x[1], reverse=True)
    
    total_value = 0
    for value, weight in items:
        if capacity >= weight:
            total_value += value
            capacity -= weight
        else:
            # Take fraction
            total_value += value * (capacity / weight)
            break
    
    return total_value

✅ When Greedy Works

  • Greedy Choice Property: A locally optimal choice leads to globally optimal solution
  • Optimal Substructure: Optimal solution contains optimal solutions to subproblems
  • Common examples: Huffman coding, Dijkstra's shortest path, Prim's/Kruskal's MST
Step 0 — Click Step Step to advance one step at a time
🧭

Understanding Algorithm Colors

White
Undiscovered
Grey
In Queue/Stack
Black
Processed
Green
Start Node
Red
Goal Node

BFS uses Queue (FIFO) — explores level by level, always finds shortest path in unweighted graphs

Processed
In Queue / Unvisited
0
Explored
Path
0
Step
Speed: 1x

🎲 Random Graph Generator

📝 Edge List Input

LIVE SYNC

💡 Type edges here and they'll appear on the canvas instantly. Format: "u v [w]"

Q
Visited
Distance
Parent

🌊 The Two Explorers

Imagine two explorers trying to find treasure in a maze:

BFS (The Cautious Explorer) checks every room at each distance level before going deeper. She's systematic—first all rooms 1 step away, then 2 steps, then 3. This guarantees finding the shortest path!

DFS (The Adventurous Explorer) picks a path and follows it as deep as possible before backtracking. He might find the treasure quickly if he's lucky, but his path isn't always the shortest.

📊 Arrays
Current State: [5, 12, 8, 3, 15, 7]
Input:

What is an Array?

An array is a collection of items stored at contiguous memory locations. The idea is to store multiple items of the same type together.

Access
O(1)
Search
O(n)
Insert
O(n)
Delete
O(n)

Comparisons

Structure Access Search Insert Delete
Array O(1) O(n) O(n) O(n)
Linked List O(n) O(n) O(1)* O(1)*

Think of it like: A Parking Lot Row

An array is like a row of numbered parking spots. Each spot has a fixed number. You can instantly park in spot #5. But if you want to add a *new* spot between #3 and #4, you'd have to repaint all the lines and move every car down one spot!

🎯 Scenario: Music Playlist

Manage a playlist of 100 songs:

  • Play song #42: Instant O(1). Great!
  • Add song at #1: Slow O(n). Must shift 99 songs.
  • Shuffle: Easy O(n) swaps.

Solution

Use Arrays when you need fast random access and size doesn't change often. For frequent insertions/deletions, consider a Linked List.

📚 Stacks
Top Element: [15]
Input:

📊 Stack vs Queue Comparison

Aspect Stack (LIFO) Queue (FIFO)
Principle Last In, First Out First In, First Out
Add push() → Top enqueue() → Back
Remove pop() ← Top dequeue() ← Front
Peek peek() → Top front() → Front
Use Cases Undo, Recursion, Parentheses BFS, Scheduling, Print Queue
Push/Pop
O(1)
Peek
O(1)
Search
O(n)

Think of it like: Pancake Stack

You can only add a pancake on top, and you can only eat the top pancake first. The first pancake you made is the last one you'll eat!

🎯 Scenario: Browser Back Button

You visit these pages in order:

  1. google.com
  2. youtube.com
  3. youtube.com/video123
  4. twitter.com

You press "Back" twice. Where are you now?

Solution: youtube.com

Browsers use a stack for history!

1
First Back: Pop twitter → Now at youtube.com/video123
2
Second Back: Pop video123 → Now at youtube.com ✓
🎫 Queues
Front Element: [3]
Input:

Key Operations

  • enqueue(x) Add x to the BACK (Wait in line).
  • dequeue() Remove from the FRONT (Next please!).
  • front() Look at who is first without removing them.

Think of it like: The Bus Stop

The first person to arrive at the bus stop is the first one to get on the bus. If you come late, you go to the back of the line!

🎯 Scenario: Printer Spooler

Three people send documents to print:

  1. Alice sends "Resume.pdf" (10:00 AM)
  2. Bob sends "Photo.jpg" (10:01 AM)
  3. Charlie sends "Homework.docx" (10:02 AM)

If the printer jams on the first job, which file is stuck?

Solution: Resume.pdf

Queues are FIFO. Alice was first in, so she is first out (to the printer).

🔗 Linked Lists
Type:
Inputs: @

The Classic Chain

Unlike arrays, Linked Lists don't need contiguous memory. Each node holds data and a pointer to the next one. Great for insertions where you don't want to shift everything!

🔗 Variants Comparison

Variant Prev Ptr Circular Best Use
Singly Stacks, Simple lists
Doubly Browser History
Circular Music Playlists
Insert (at head)
O(1)
Search
O(n)

Think of it like: Treasure Hunt

Each clue tells you strictly where to find the next clue. You can't skip ahead—you must follow the chain from the beginning!

🎯 Scenario: Music Playlist

You want a "Repeat All" mode where the last song plays the first song next. Which structure is best?

Solution: Circular Linked List

Circular: The Tail points back to Head, creating an infinite loop. Perfect for playlists!
🌳 Binary Search Trees
Root: 50
Value:
Animations:

The Self-Organizing Tree

Everything to the left is smaller. Everything to the right is bigger. This simple rule turns searching from O(n) into O(log n). It's like a dictionary that organizes itself!

🌲 BST Properties

  • L Left Subtree: All nodes are < than root.
  • R Right Subtree: All nodes are > than root.
  • U Unique: Ideally no duplicate values.
Search (Avg)
O(log n)
Insert (Avg)
O(log n)

*Worst case O(n) if unbalanced (like a line)

Think of it like: Filing System

Files A-M go in the top drawer, N-Z in the bottom. Inside A-M, A-F is left, G-M is right. You eliminate half the possibilities with every step!

🚶 Traversal Types

In-Order
Left, Root, Right
(Sorted!)
Pre-Order
Root, Left, Right
(Copy)
Post-Order
Left, Right, Root
(Delete)

⛰️ Heaps

The "King of the Hill" data structure. Always gives you the max (or min) element instantly.

Input:
Array: []

📐 Array Index Formulas

Heaps are complete binary trees stored efficiently in arrays:

Left Child 2*i + 1
Right Child 2*i + 2
Parent floor((i-1)/2)
Insert
O(log n)
Extract
O(log n)
Peek
O(1)

Think of it like: Hospital ER

In an ER, patients are treated by severity (Priority), not arrival time. The most critical patient is always moved to the front. That's a Priority Queue!

Why Arrays?

Because heaps are Complete Binary Trees (filled left-to-right), we don't need pointers! We can just use math index calculations. This makes heaps extremely memory efficient and cache-friendly.

#️⃣ Hash Tables
Next Hash: 0
Key:
Value:

⚡ Speed & Efficiency

Perfect for lookups (Maps, Sets, Caches).

Avg Access
O(1)
Worst Case
O(n)
Load Factor
< 0.7

*Worst case happens when many keys collide (end up in same bucket)

Think of it like: Labeled Bins

You sort mail into 26 bins (A-Z). To find "Mom's" letter, you go straight to bin 'M'. You don't check 'A', 'B', 'C'...

💥 Handling Collisions

What if "Mom" and "Mike" both go to bin 'M'?

🔗 Chaining (This Demo)

Just make a list! Both letters stay in bin 'M', one after another.

🏃 Open Addressing

"Bin 'M' is full? I'll try 'N' next." (Linear Probing)

🎯 Scenario: Phone Contacts

You have 500 contacts. When you tap "Alice", how does it find her number instantly without checking 500 names?

Step 1: Hash("Alice") → 42
Step 2: Go to Index 42

🕸️ Interactive Graph Editor

Build, visualize, and explore graphs with real-time feedback

📝 Edge List Input

Live Sync
Force Mode: Drag nodes to reposition. Physics simulation keeps graph organized.

📊 Properties

Vertices 0
Edges 0
🌳 Is Tree?
🔗 Connected?
🔄 Has Cycle?

The Social Network

Facebook friend suggestions? That's graph theory! Each person is a node, each friendship is an edge.

"People you may know" = friends of friends = nodes 2 edges away!

📋 Graph Terminology

Vertex (Node) A point in the graph
Edge Connection between two vertices
Directed Edges have direction (A→B)
Undirected Edges go both ways (A↔B)
Weighted Edges have values (distances)
Degree Number of edges connected to a node

🗃️ How to Store Graphs

Adjacency List (Most Common)

Each node stores list of neighbors. Space: O(V+E)

graph = {
  'A': ['B', 'C'],
  'B': ['A', 'D'],
  'C': ['A', 'D'],
  'D': ['B', 'C']
}
Adjacency Matrix

2D array where matrix[i][j]=1 if edge exists. Space: O(V²)

📊 Adjacency List vs Matrix Comparison

Operation Adjacency List Adjacency Matrix
Space O(V + E) O(V²)
Check Edge (A→B)? O(degree) O(1)
Find All Neighbors O(degree) O(V)
Add Edge O(1) O(1)
Best For Sparse graphs (few edges) Dense graphs (many edges)
BFS/DFS
O(V+E)
Traversal
O(V+E)
All Pairs
O(V³)*

*Floyd-Warshall algorithm for all-pairs shortest paths.

🌊 BFS (Breadth-First Search)

Explore level by level. Uses a queue. Good for shortest path in unweighted graphs.

Python
from collections import deque

def bfs(graph, start):
    visited = set()
    queue = deque([start])
    visited.add(start)
    
    while queue:
        node = queue.popleft()
        print(node)  # Process node
        
        for neighbor in graph[node]:
            if neighbor not in visited:
                visited.add(neighbor)
                queue.append(neighbor)

🏔️ DFS (Depth-First Search)

Go deep before backtracking. Uses a stack (or recursion). Good for detecting cycles.

Python
def dfs(graph, node, visited=None):
    if visited is None:
        visited = set()
    
    visited.add(node)
    print(node)  # Process node
    
    for neighbor in graph[node]:
        if neighbor not in visited:
            dfs(graph, neighbor, visited)

🎯 BFS vs DFS

Aspect BFS DFS
Data Structure Queue Stack / Recursion
Shortest Path Yes (unweighted) No
Space O(width of graph) O(depth of graph)
Use Case Shortest path, level order Cycle detection, topological sort

🔄 Cycle Detection

Detecting cycles is crucial for many algorithms!

Undirected DFS: if you visit a node already in your path
Directed Track "in-progress" nodes (gray color in 3-color scheme)
Linked List Floyd's Tortoise & Hare (slow/fast pointer)

🗺️ Common Graph Algorithms

Dijkstra's Shortest path (weighted, non-negative)
Bellman-Ford Shortest path (negative weights OK)
Topological Sort DAG ordering (prerequisites, build order)
MST (Prim/Kruskal) Minimum spanning connections

🎯 Scenario: Course Prerequisites

You have courses with prerequisites: CSE110 → CSE220 → CSE300. How do you find a valid course order?

Solution: Topological Sort!

Model courses as nodes, prerequisites as directed edges. Topological sort gives a valid order!

1 Build graph: CSE110 → CSE220 → CSE300
2 DFS post-order reverse = [CSE110, CSE220, CSE300] ✓

🎮 Choose Your Data Structure

💡 Array: Access O(1) • Insert/Delete O(n) • Best for indexed access
Your Data Structure
[5, 12, 8, 3, 15]
💡 Tip: Try different data structures to see how operations differ!

☕ The Coffee Shop Database

You’re helping a cozy coffee shop understand customers, orders, and sales. This dataset is small but realistic—perfect for learning.

Tip: Press Ctrl/Cmd + Enter to run your query.

🧠 First Win (60 seconds)

Click Run to see the first 10 products.

Loading SQL Engine…
Output limited to 200 rows

🧾 Entity-Relationship Diagram

👤 customers
🔑 id INTEGER PK
name TEXT
city TEXT
📦 products
🔑 id INTEGER PK
name TEXT
category TEXT
price_cents INTEGER
🧾 orders
🔑 id INTEGER PK
🔗 customer_id → customers.id
order_date TEXT
📋 order_items
🔗 order_id → orders.id
🔗 product_id → products.id
qty INTEGER

🔑 = Primary Key   🔗 = Foreign Key

🔍 Dataset Preview

See a few rows so you can write queries confidently.

📊 Results

Run a query to see results.

🧭 SQL Lab Guide

Use the Lab when you want to explore freely. For structured challenges with validation and hints, go to SQL Practice.

Learning trick: Dual coding

Read the story + see the schema + run a query. You’re combining verbal + visual information, which improves memory and understanding.

🎯 Mini Challenge

Question: Which customers placed orders in 2025?

Hint: join customersorders and filter by date.

Try it in the editor. If you get stuck, go to SQL Practice for guided hints.

Choose a challenge

Solve it, then hit Check Answer. Your progress saves automatically.

XP: 0 Streak: 0

Loading…

🧩 Hints (progressive)

Attempts: 0
Ready.

🎯 Expected Output

Your result must match this output (columns + rows). Some challenges allow any order.

📊 Your Output

Run check to see results.

🧾 Diff (premium feedback)

No diff yet.

🏆 How you win

Fast onboarding, instant feedback, and tiny tasks. Don’t aim for perfection—aim for reps.

Run
Instant
Hints
3 tiers
Validation
Diff

🧠 Active Recall Tip

After you solve a challenge, reset and re-type the query from memory. This is one of the fastest ways to build real skill—especially if you’re not confident with coding yet.

📖 Lesson 1: SELECT Basics

SELECT is how you retrieve data from a database. Think of it like asking a question.

Syntax

SELECT column1, column2
FROM table_name;
💡

Key Points

  • SELECT * gets all columns
  • SELECT name, price gets specific columns
  • AS renames columns: price AS cost
🎯 Try it: Go to SQL Lab and run:
SELECT name, price_cents FROM products;

📖 Lesson 2: Filtering with WHERE

WHERE filters rows based on conditions. Only matching rows are returned.

Syntax

SELECT * FROM products
WHERE category = 'Coffee';
🔧

Operators

  • = equal, != not equal
  • <, >, <=, >= comparisons
  • AND, OR combine conditions
  • IN ('a', 'b') matches any in list
  • LIKE '%pattern%' text matching

📖 Lesson 3: JOIN - Combining Tables

JOIN connects rows from different tables using a common column (like customer_id).

INNER JOIN

Only matching rows from both tables

LEFT JOIN

All from left table + matching from right

RIGHT JOIN

Matching from left + all from right

Rarely used—just swap table order with LEFT JOIN

FULL OUTER JOIN

All from both tables, NULL where no match

Great for finding orphan records

Syntax

SELECT c.name, o.order_date
FROM customers c
JOIN orders o ON o.customer_id = c.id;

📖 Lesson 4: GROUP BY - Aggregations

GROUP BY combines rows with the same value, allowing you to use aggregate functions.

Aggregate Functions

COUNT(*) - rows
SUM(col) - total
AVG(col) - average
MIN(col) - smallest
MAX(col) - largest
COUNT(DISTINCT) - unique

Example

SELECT category, COUNT(*) AS total
FROM products
GROUP BY category;
⚠️

HAVING vs WHERE

WHERE filters before grouping.
HAVING filters after grouping (on aggregates).

Coming soon

Timed drills + common patterns (joins, group by, subqueries) with fast feedback.

✍️ Write Your Query

Quick Add Query:

📊 Live Data Table

💡 Run INSERT, UPDATE, or DELETE to see changes instantly!

📝 Quick SQL Reference

INSERT
INSERT INTO table (col1, col2)
VALUES (val1, val2);
UPDATE
UPDATE table
SET col = value
WHERE condition;
DELETE
DELETE FROM table
WHERE condition;

🎮 Interactive ERD Builder

Think of it like: Organization Chart

An ERD (Entity-Relationship Diagram) is a simple visual way to show how data is organized in a database. It uses boxes to represent things (called entities) like students, products, or orders, and lines to show how these things are connected to each other (called relationships). ERD helps us easily understand what data is stored, what information each item has, and how different data pieces are related, even before creating the actual database.

📐 ERD Components

Symbol Name Purpose
▭ Rectangle Entity A "thing" we store data about
◇ Diamond Relationship How entities connect
⬭ Ellipse Attribute Properties of an entity
Underline Primary Key Unique identifier

🔢 Cardinality Notations

Type Chen Example
One-to-One 1 : 1 Person → Passport
One-to-Many 1 : N Department → Employees
Many-to-Many M : N Students ↔ Courses

🎯 Design Challenge

Scenario: Design an ERD for a Library System with:

  • Books (ISBN, title, author, year)
  • Members (ID, name, email, join_date)
  • Loans (book borrowed, member, due_date)

💡 Hint: What's the relationship between Members and Books?

Solution Insight

Members ← BORROWS → Books is a M:N relationship!

One member can borrow many books, and one book can be borrowed by many members (over time). The LOANS table captures this relationship with additional attributes.

🎮 EERD Hierarchy Builder

💡 Tip: Drag entities to reposition. The sample shows PERSON specializing into STUDENT, EMPLOYEE, and INSTRUCTOR.

Think of it like: Family Tree

An EERD (Enhanced Entity-Relationship Diagram) is an advanced version of an ERD that shows more detailed and complex relationships in a database. It not only represents entities and their relationships but also includes special features like subclasses, inheritance, and constraints. EERD helps in clearly modeling real-world systems where one entity can have different types, making the database design more accurate and easier to understand.

📐 EER Concepts

Specialization Top-down: Define subclasses from superclass
Generalization Bottom-up: Combine entities into superclass
Inheritance Subclass inherits all superclass attributes
ISA Relationship "STUDENT is a PERSON"

🔒 Specialization Constraints

Disjoint vs Overlapping

d Disjoint: Entity can belong to only ONE subclass
o Overlapping: Entity can belong to MULTIPLE subclasses

Total vs Partial

══ Total: Every superclass instance MUST be in a subclass
── Partial: Superclass instance MAY exist without subclass

🎯 Modeling Challenge

Scenario: A university system has VEHICLES. Some are CARS (with num_doors), some are MOTORCYCLES (with engine_cc). A vehicle cannot be both.

Question: Is this disjoint or overlapping? Total or partial?

Solution

Disjoint (d) — A vehicle is either a car OR motorcycle, not both.

Partial — Could have other vehicles (trucks, bikes) not yet modeled.

📊 Sample Tables

These tables are used for all operations below.

👤 Students

id name major gpa
1 Alice CS 3.8
2 Bob Math 3.5
3 Carol CS 3.9
4 David Physics 3.2

📚 Enrollments

student_id course grade
1 DB101 A
1 AI201 B+
2 DB101 A-
3 AI201 A
4 PHY101 B

📖 Operator Reference

σ (sigma)
Selection - Filter rows
π (pi)
Projection - Select columns
⨝ (join)
Natural Join - Combine tables
∪ (union)
Union - Combine row sets
∩ (intersect)
Intersection - Common rows
− (minus)
Difference - Subtract rows
× (cross)
Cartesian Product - All pairs
ρ (rho)
Rename - Change column name

σ Selection (Filter Rows)

Like SQL's WHERE clause - keeps rows matching a condition.

σ (Students)

π Projection (Select Columns)

Like SQL's SELECT column list - picks specific columns.

π (Students)

⨝ Natural Join

Combines tables on matching column values (Students.id = Enrollments.student_id).

Students ⨝ Enrollments ON id = student_id

🧩 Combined Expression

Try chaining operations like a real query:

πname, course, grade ( σmajor='CS'(Students) ⨝ Enrollments )

This is equivalent to:
SELECT name, course, grade FROM Students JOIN Enrollments ON id = student_id WHERE major = 'CS'

🔄 Relational Algebra ↔ SQL Mapping

Relational Algebra SQL Equivalent Purpose
σmajor='CS'(Students) SELECT * FROM Students WHERE major = 'CS' Filter rows
πname, gpa(Students) SELECT name, gpa FROM Students Select columns
Students ⨝ Enrollments SELECT * FROM Students JOIN Enrollments ON id = student_id Combine tables
Students ∪ Alumni SELECT * FROM Students UNION SELECT * FROM Alumni Combine row sets

🔒 ACID Properties

A

Atomicity

All or nothing. If any part fails, the entire transaction rolls back.

C

Consistency

Database moves from one valid state to another. All rules/constraints are satisfied.

I

Isolation

Concurrent transactions don't interfere with each other (as if executed serially).

D

Durability

Once committed, data persists even if the system crashes.

📊 Isolation Levels

Level Dirty Read Non-Repeatable Phantom
READ UNCOMMITTED ❌ Possible ❌ Possible ❌ Possible
READ COMMITTED ✅ Prevented ❌ Possible ❌ Possible
REPEATABLE READ ✅ Prevented ✅ Prevented ❌ Possible
SERIALIZABLE ✅ Prevented ✅ Prevented ✅ Prevented

🎮 Transaction Simulator

Watch two transactions execute concurrently and see potential anomalies.

📦 Database State

Account Balance
$1000
Committed?
✅ Yes

🅰️ Transaction A

Waiting to start...
Status: Idle

🅱️ Transaction B

Waiting to start...
Status: Idle

📖 Dirty Read Explained

A Dirty Read occurs when Transaction B reads data that Transaction A has modified but not yet committed. If A rolls back, B has read "phantom" data that never existed.

T1: UPDATE accounts SET balance = 500 WHERE id = 1;
T2: SELECT balance FROM accounts WHERE id = 1; -- Reads 500 (uncommitted!)
T1: ROLLBACK; -- Balance reverts to 1000
T2 now has incorrect data!

🎮 Operations

📊 Tree Statistics

Keys:
0
Height:
1
Nodes:
1
Order:
4
📚

Why B-Trees?

B-Trees keep data sorted and allow searches, insertions, and deletions in O(log n) time. They're the backbone of database indexes because they minimize disk reads.

🌳 B+ Tree Visualization

💡 Tip: Insert values and watch nodes split when they overflow!

📝 Operation Log

Operations will appear here...

📖 B-Tree Properties

🔢 Order (m)

  • Max m children per node
  • Max m-1 keys per node
  • Min ⌈m/2⌉ children (except root)

⚡ Complexity

  • Search: O(log n)
  • Insert: O(log n)
  • Delete: O(log n)

💾 Database Use

  • CREATE INDEX uses B-Trees
  • Leaf nodes store row pointers
  • Non-leaf nodes are navigation aids

🤔 Why NoSQL?

Relational databases (SQL) are great for structured data and complex queries, but they struggle with:

  • 📉 Scalability: Hard to scale horizontally (sharding is complex).
  • 🔄 Flexibility: Schema changes require downtime or migrations.
  • Speed: Joins can be slow for massive datasets.

NoSQL (Not Only SQL) databases emerged to solve these problems by trading ACID guarantees for performance and scalability (CAP Theorem).

📦 Types of NoSQL

📄 Document Stores (e.g., MongoDB)

Data is stored as JSON-like documents. Flexible schema.
Best for: Content management, catalogs, user profiles.

    {
      "_id": 1,
      "name": "Alice",
      "skills": ["Java", "Python"]
    }
🔑 Key-Value Stores (e.g., Redis)

Simple hash table. Extremely fast.
Best for: Caching, session management, leaderboards.

🕸️ Graph Databases (e.g., Neo4j)

Nodes and edges. Optimized for relationships.
Best for: Social networks, recommendation engines.

📊 Column-Family (e.g., Cassandra)

Wide-column stores. High write throughput.
Best for: Time-series data, IoT logs.

🆚 SQL vs NoSQL

Feature SQL (Relational) NoSQL (Non-Relational)
Schema Fixed, rigid Dynamic, flexible
Scaling Vertical (bigger server) Horizontal (more servers)
Data Structured (Tables) Unstructured (Docs, Graphs)
Transactions ACID (Strong consistency) BASE (Eventual consistency)
⚖️

The CAP Theorem

In a distributed system, you can only have 2 of the 3:

  • Consistency: Everyone sees the same data at the same time.
  • Availability: The system is always up.
  • Partition Tolerance: The system works even if network fails.

SQL usually chooses CA. NoSQL usually chooses AP or CP.

🎮 Schema Level Viewer

Think of it like: Building Blueprint Levels

External: What tenants see (apartment layouts)
Conceptual: Architect's blueprint (structure)
Internal: Engineering specs (pipes, wiring)

📐 Three-Level Architecture

Level Purpose Users
External User views, subsets of data End users, Apps
Conceptual Logical structure, entities, relationships DBAs, Designers
Internal Physical storage, indexes, files System, DBMS

🔓 Data Independence

Logical Independence Change conceptual schema without affecting external views
Physical Independence Change internal storage without affecting conceptual schema

💡 This is why you can add indexes or move files without rewriting SQL queries!

🎯 Quick Check

Question: A company wants to switch from HDD storage to SSD. Which level changes, and does the SQL code need to be rewritten?

Answer

Only the Internal Level changes (file storage location).

No SQL changes needed! Physical independence protects the conceptual and external levels from storage changes.

🎮 Step-by-Step Normalization

Step 0/4

Think of it like: Decluttering a Room

Normalization is the process of organizing data in a database to keep it clean and efficient. It helps remove repeated data, reduce errors, and make sure each piece of information is stored in the right place. By breaking large tables into smaller, well-structured ones and linking them properly, normalization makes databases easier to manage, update, and maintain.

📐 Normal Forms

Form Rule
1NF Atomic values only (no repeating groups)
2NF 1NF + No partial dependencies on PK
3NF 2NF + No transitive dependencies
BCNF Every determinant is a candidate key

🔗 Functional Dependencies

A functional dependency X → Y means: if you know X, you can determine Y.

Full FD Y depends on ALL of X (no subset)
Partial FD Y depends on only PART of composite PK
Transitive FD X → Y → Z (indirect dependency)

⚠️ Data Anomalies

Insert Can't add data without adding unrelated data
Update Must update same info in multiple places
Delete Deleting one thing removes unrelated info

🎯 Quick Practice

Table: StudentCourse(StudentID, CourseID, StudentName, CourseName, Grade)

PK: (StudentID, CourseID)

Question: Is StudentName a partial or full dependency?

Show Answer

Partial dependency! StudentName depends only on StudentID, not the full composite key (StudentID, CourseID). This violates 2NF.

📚 Choose a Topic

🔥 0 day streak
0 completed
⏰ New challenge in --:--:--
TODAY
Medium SQL Query

Loading today's challenge...

Please wait while we fetch your daily challenge.

📅 Your Challenge Calendar

🔥 Completed ⭐ Perfect ❄️ Freeze used ⬜ Missed

📜 Recent Challenges

Complete today's challenge to start your history!

🏯 The Tower of Hanoi

In an ancient temple, monks must move 64 golden disks from one pillar to another. But there are sacred rules: only one disk at a time, and a larger disk can never rest on a smaller one.

The head monk realized a profound truth: "To move 64 disks, I must first move 63 disks. To move 63 disks, I must first move 62..." This is recursion—solving a big problem by solving smaller versions of itself!

🧠 The Recursion Pattern

function solveRecursively(problem) {
  // Base case: simplest problem
  if (problem is tiny) {
    return simple solution
  }

  // Recursive case: break down
  smaller = makeProblemSmaller(problem)
  return solveRecursively(smaller)
}

Think of it like: Russian Nesting Dolls

Each doll contains a smaller doll inside. To find the tiniest doll, you keep opening dolls until there's nothing left to open. That's your base case!

🎯 Key Insight

Every recursive function needs:

  1. Base case: When to stop (prevents infinite loop!)
  2. Recursive case: How to make the problem smaller
  3. Progress: Each call must move toward base case

🧪 Recursion Sandbox: Fibonacci Call Stack

Watch how recursive calls stack up and unwind. Enter a number to see fib(n) visualized!

Result:
Calls Made
0
Max Depth
0
📚 Call Stack (grows down):
Click "Visualize" to see the call stack

💡 Notice: fib(5) makes 15 calls! Each increase in n nearly doubles the calls. This is why recursive Fibonacci is O(2ⁿ) - exponential time! Memoization can fix this.

🏁 Race Day at Algorithm Stadium

Five racers compete on a special track. The track's length is determined by the input size (n). With a small input (n=10), all racers finish quickly. But watch what happens as n grows...

🏆 The Contestants

O(1)The Flash — Constant time, always instant
O(log n)The Strategist — Divides problem in half each step
O(n)The Steady Runner — Checks every item once
O(n log n)The Smart Sorter — Efficient sorting
O(n²)The Slowpoke — Checks every pair

💡 The Lesson

At n=10, all racers seem similar.

At n=100, differences become clear.

At n=1000, slow algorithms become unusable!

Big O tells us how algorithms scale. Always pick the fastest racer for your track!

👆

Selection Sort

Beginner • 10 min

Select the smallest element each pass.

+100 XP
📥

Insertion Sort

Beginner • 10 min

Insert each element into sorted position.

+100 XP
🏔️

Heap Sort

Intermediate • 12 min

Build a heap and extract elements.

+150 XP
📏

Linear Search

Beginner • 8 min

Check every element one by one.

+100 XP
🌊

Breadth-First Search

Intermediate • 12 min

Explore level by level for shortest path.

+150 XP
🔍

Depth-First Search

Intermediate • 11 min

Dive deep before backtracking.

+150 XP
📍

Dijkstra's Algorithm

Intermediate • 14 min

Weighted shortest path algorithm.

+150 XP

A* Pathfinding

Advanced • 14 min

Smart heuristic-guided pathfinding.

+200 XP
🎯

Greedy Best-First

Intermediate • 10 min

Fast heuristic-only pathfinding.

+150 XP

🧠 Practice Problems with Walkthroughs

Click any problem to see both Naive (O(n²)) and Optimal solutions visualized step-by-step!

EASY

Two Sum

Find two numbers that add up to target

HashMap
🐢 O(n²)🚀 O(n)
EASY

Binary Search

Find target in sorted array

Divide & Conquer
🐢 O(n)🚀 O(log n)
EASY

Contains Duplicate

Check if array has duplicates

HashSet
🐢 O(n²)🚀 O(n)

Algorithm Masterclass

Deep dive into the logic behind the code. Watch step-by-step visual walkthroughs, analyze time complexity, and master the fundamentals of computer science.

12 Modules
4.5h Content
XP+ Rewards
🫧
Sorting Algorithms

Bubble Sort

The foundations of sorting. Learn how adjacent swapping ripples data into place.

Beginner 12m +100 XP
Divide & Conquer

Quick Sort

Master the industry-standard sorting algorithm using pivot partitioning logic.

Intermediate 15m +150 XP
🔀
Divide & Conquer

Merge Sort

Learn stable sorting by recursively splitting and merging sorted subarrays.

Intermediate 14m +150 XP
🔍
Search Algorithms

Binary Search

Eliminate half the data at every step. The gold standard for sorted search.

Beginner 10m +100 XP
🌊
Graph Traversal

Breadth-First Search

Explore graphs layer by layer. Essential for finding shortest paths.

Intermediate 18m +200 XP

Data Structure Deep Dive

Understand how data is organized, managed, and stored. Master the building blocks of efficient software, from Linked Lists to complex Graphs.

8 Modules
3.2h Content
XP+ Rewards
📚
Linear Data Structures

Stack Operations

Master LIFO (Last-In-First-Out) with Push, Pop, and Peek operations.

Beginner 10m +100 XP
🔗
Linear Data Structures

Linked List Traversal

Navigate node chains manually. Understand pointers and dynamic memory.

Beginner 11m +100 XP
🌳
Tree Data Structures

Binary Tree Traversal

Explore Pre-order, In-order, and Post-order recursive patterns.

Intermediate 14m +150 XP
🎫
Linear Data Structures

Queue Operations

Master FIFO (First-In-First-Out) with Enqueue and Dequeue logic.

Beginner 10m +100 XP
🗂️
Advanced Data Structures

Hash Table Magic

Understand key-value mapping, collisions, and O(1) average lookup.

Intermediate 14m +150 XP
📊
Linear Data Structures

Array Deep Dive

Memory layout, resizing logic, and multi-dimensional array access.

Beginner 12m +100 XP
Coming Soon
⛰️

Heap & Priority Queue

Intermediate • 15 min

Min/Max heap, heapify, and applications.

+150 XP Coming Soon
🌊

BFS - Level by Level

Intermediate • 12 min

Breadth-first search with queue visualization.

+150 XP Coming Soon
🕳️

DFS - Go Deep First

Intermediate • 12 min

Depth-first search with recursion animation.

+150 XP Coming Soon

🌱 Beginner Level

📊

SELECT Basics

Beginner • 12 min

Querying data with SELECT, WHERE, ORDER BY, DISTINCT, and aliases.

+100 XP
🏗️

DDL Operations

Beginner • 10 min

CREATE, ALTER, DROP, TRUNCATE - defining database structure.

+100 XP
✏️

DML Operations

Beginner • 10 min

INSERT, UPDATE, DELETE - manipulating data in tables.

+100 XP

📈 Intermediate Level

🔗

JOIN Operations

Intermediate • 18 min

INNER, LEFT, RIGHT, FULL, CROSS, and SELF joins explained.

+150 XP
🧮

Aggregate Functions

Intermediate • 15 min

COUNT, SUM, AVG, GROUP BY, and HAVING for data analysis.

+150 XP
🔄

Subqueries

Intermediate • 14 min

Nested queries, correlated subqueries, IN, and EXISTS.

+150 XP

🚀 Advanced Level

🪟

Window Functions

Advanced • 20 min

ROW_NUMBER, RANK, LAG, LEAD, and running totals.

+200 XP
📦

Common Table Expressions

Advanced • 14 min

WITH clause and recursive CTEs for cleaner queries.

+200 XP
🔒

Transactions & ACID

Advanced • 16 min

COMMIT, ROLLBACK, isolation levels, and data integrity.

+200 XP

Indexes & Performance

Advanced • 16 min

B-trees, composite indexes, EXPLAIN, and optimization.

+200 XP
👁️

Views

Advanced • 12 min

Virtual tables and materialized views for reusability.

+175 XP
Message