Student starter code (30% baseline)
index.html- Main HTML pagescript.js- JavaScript logicstyles.css- Styling and layoutpackage.json- Dependenciessetup.sh- Setup scriptREADME.md- Instructions (below)๐ก Download the ZIP, extract it, and follow the instructions below to get started!
Welcome to Activity 07! This template teaches you advanced query techniques including subqueries, views, and Common Table Expressions (CTEs) using a realistic sales database system.
By completing this activity, you will:
IMPORTANT: This template includes WORKING CODE! You can see results immediately:
Download SQLite Browser (if you don't have it):
Open the database files:
sales.dbsqlite/schema.sql -> Click "Execute" โถ๏ธsample-data.sql -> Click "Execute" โถ๏ธRun the queries:
sqlite/queries.sql# Make sure you're in the activity folder, then:
docker-compose up -d
# Access MySQL:
docker exec -it w4-mysql mysql -u root -plearning123 contacts_db
# Then load schema:
source /docker-entrypoint-initdb.d/schema.sql;
# Access PostgreSQL:
docker exec -it w4-postgres psql -U postgres contacts_db
# Then load schema:
\i /docker-entrypoint-initdb.d/schema.sql
postgresql/schema.sql and sample-data.sql70% of the code is implemented for you:
Location: sqlite/queries.sql line 253
Your Task: Find customers with above-average order totals using a subquery
Success Criteria:
Hints:
WHERE total_spent > (SELECT AVG(...) FROM ...)Expected Output:
customer_name | email | total_spent | avg_order_value
Carol White | carol.w@email.com | 869.92 | 289.97
Alice Johnson | alice.j@email.com | 729.89 | 182.47
...
Why This Matters: Identifying high-value customers helps target marketing campaigns and loyalty programs effectively.
Location: sqlite/queries.sql line 283
Your Task: Create product ranking by revenue using subquery or window function
Success Criteria:
SUM(quantity * unit_price)Hints:
ROW_NUMBER() OVER (ORDER BY total_revenue DESC) for rankingCOALESCE(SUM(...), 0) to handle NULL revenuesExpected Output:
rank | product_name | category | total_revenue
1 | Smart Watch | Electronics | 2249.91
2 | Denim Jeans | Clothing | 1879.82
3 | Laptop Stand | Electronics | 1599.60
...
40 | Product X | Books | 0.00
Why This Matters: Revenue ranking helps with inventory management, promotional planning, and understanding which products drive business success.
Location: sqlite/queries.sql line 323
Your Task: Create a comprehensive sales dashboard view using CTEs or complex JOINs
Success Criteria:
sales_dashboardHints:
WITH order_details AS (
SELECT ... FROM orders WHERE status = 'completed'
),
enriched_items AS (
SELECT ... JOIN order_details ...
)
CREATE VIEW sales_dashboard AS
SELECT ... FROM enriched_items ...
CREATE VIEW sales_dashboard AS
SELECT
c.name AS customer_name,
c.city AS customer_city,
...
FROM customers c
JOIN orders o ON c.id = o.customer_id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
WHERE o.status = 'completed';
Expected Output (when querying view):
SELECT * FROM sales_dashboard LIMIT 10;
customer_name | customer_city | order_id | product_name | quantity | line_total
Alice Johnson | NYC | 1 | Wireless Headphones| 2 | 159.98
Alice Johnson | NYC | 1 | USB-C Cable | 1 | 12.99
Bob Smith | NYC | 2 | Running Shoes | 1 | 89.99
...
Why This Matters: Dashboard views simplify complex business reporting, provide consistent data access, and enable non-technical users to query business intelligence data easily.
Customers Table (30 records)
| Field | Type | Purpose | Example |
|---|---|---|---|
id |
INTEGER | Unique identifier | 1, 2, 3... |
name |
TEXT | Customer name | "Alice Johnson" |
email |
TEXT | Email (unique) | "alice.j@email.com" |
city |
TEXT | Location | "NYC", "LA", "Chicago" |
registration_date |
DATE | Sign-up date | "2023-08-15" |
loyalty_tier |
TEXT | Member level | Bronze, Silver, Gold, Platinum |
Products Table (40 records)
| Field | Type | Purpose | Example |
|---|---|---|---|
id |
INTEGER | Unique identifier | 1, 2, 3... |
name |
TEXT | Product name | "Wireless Headphones" |
category |
TEXT | Product type | Electronics, Clothing, Home, Sports, Books |
price |
DECIMAL | Unit price | 79.99 |
stock_quantity |
INTEGER | Inventory count | 150 |
supplier |
TEXT | Vendor name | "TechSupply Co" |
Orders Table (80 records)
| Field | Type | Purpose | Example |
|---|---|---|---|
id |
INTEGER | Unique identifier | 1, 2, 3... |
customer_id |
INTEGER | Foreign key | 5 |
order_date |
DATE | Purchase date | "2024-03-15" |
total_amount |
DECIMAL | Order total | 249.99 |
status |
TEXT | Order state | pending, completed, cancelled |
Order Items Table (200+ records)
| Field | Type | Purpose | Example |
|---|---|---|---|
id |
INTEGER | Unique identifier | 1, 2, 3... |
order_id |
INTEGER | Foreign key | 10 |
product_id |
INTEGER | Foreign key | 25 |
quantity |
INTEGER | Items ordered | 2 |
unit_price |
DECIMAL | Price at time | 79.99 |
-- Simple subquery in WHERE
WHERE customer_id IN (SELECT customer_id FROM orders WHERE ...)
-- Subquery in SELECT (scalar subquery)
SELECT name, (SELECT COUNT(*) FROM orders WHERE ...) AS order_count
-- Correlated subquery (references outer query)
WHERE order_count > (SELECT AVG(order_count) FROM ...)
-- Subquery in FROM (derived table)
FROM (SELECT customer_id, SUM(total) FROM orders GROUP BY customer_id) AS totals
-- CREATE VIEW (reusable query)
CREATE VIEW customer_summary AS
SELECT ... FROM ... JOIN ... GROUP BY ...
-- Common Table Expression (CTE)
WITH sales AS (SELECT ...),
summary AS (SELECT ... FROM sales)
SELECT * FROM summary;
-- Window functions (ranking)
ROW_NUMBER() OVER (ORDER BY revenue DESC) AS rank
"No such table" error:
schema.sql AND sample-data.sqlSubquery returns multiple rows:
IN instead of = for multi-row subqueriesANY/ALL operatorsCorrelated subquery too slow:
View creation fails:
DROP VIEW IF EXISTS view_name;Window function not supported:
| Query | Expected Count/Output |
|---|---|
| Query 1 | 5-8 customers (ordered in last 30 days) |
| Query 2 | 20-25 products (top 3 categories) |
| Query 3 | 10 customers (top by lifetime value) |
| Query 4 | 8-12 customers (above-average order count) |
| Query 5 | 3 rows (status breakdown) |
| Query 6 | 15-20 customers (using view) |
| Query 7 | 30-35 rows (product sales with CTE) |
| TODO 8 | 8-12 customers |
| TODO 9 | 40 products |
| TODO 10 | 150+ rows from view |
Ready for more? Try these bonus features:
| Feature | SQLite | MySQL | PostgreSQL |
|---|---|---|---|
| Basic Subqueries | โ Full support | โ Full support | โ Full support |
| Window Functions | โ 3.25+ | โ 8.0+ | โ All versions |
| CTEs (WITH) | โ 3.8.3+ | โ 8.0+ | โ All versions |
| Recursive CTEs | โ 3.8.3+ | โ 8.0+ | โ All versions |
| Lateral Joins | โ Not supported | โ Not supported | โ Supported |
| Materialized Views | โ Manual tables | โ Manual tables | โ Native support |
SQLite & MySQL:
CREATE VIEW view_name AS
SELECT ... FROM ... WHERE ...;
PostgreSQL (with options):
CREATE OR REPLACE VIEW view_name AS
SELECT ... FROM ... WHERE ...;
-- Materialized view (PostgreSQL only)
CREATE MATERIALIZED VIEW mv_name AS
SELECT ... FROM ... WHERE ...;
REFRESH MATERIALIZED VIEW mv_name;
All three databases support similar window function syntax:
SELECT
name,
revenue,
ROW_NUMBER() OVER (ORDER BY revenue DESC) AS rank,
SUM(revenue) OVER (PARTITION BY category ORDER BY date) AS running_total
FROM products;
Your project is complete when:
Once you complete this activity, you'll have:
This skillset will serve you well in data analysis, business intelligence, and backend development roles!
Need Help?
Ready to Submit? Complete this activity and submit through the Activity Submission Form
Happy querying! ๐๏ธโจ