A production-quality SQL analytics project built on a simulated Mercari Japan marketplace. From raw data to business intelligence โ using pure SQL.
Learning repo โ mercaridb-mysql-30days This repo โ The capstone. Real business questions. Real SQL. Real insights.
This is not a tutorial follow-along.
MercariDB Analytics is a self-directed capstone project where I designed a realistic C2C marketplace database, loaded it with meaningful seed data, and then answered real business questions that a Data Analyst at Mercari Japan would actually face.
Every query in this project starts with a business question โ not a SQL exercise. The schema is normalized to 3NF. The analysis covers sellers, buyers, products, markets, and growth opportunities. The insights are written in plain language.
Built after 30 days of structured SQL study. Written from scratch.
mercaridb
โ
โโโ users โ user_id (PK), username, email, country, age, referred_by, created_at
โ
โโโ products โ product_id (PK), seller_id (FK), title, category,
โ price (DECIMAL), status, created_at
โ
โโโ orders โ order_id (PK), product_id (FK), buyer_id (FK),
โ amount (DECIMAL), order_date
โ
โโโ [your tables] โ add any extra tables you create
Relationships:
users โโ< products (one seller โ many listings)
users โโ< orders (one buyer โ many orders)
products โโ< orders (one product โ one order)
Design decisions:
DECIMAL(10,2)for all monetary values โ never FLOAT for moneyNOT NULLon all critical fields โ data integrity enforced at DB levelFOREIGN KEYconstraints โ referential integrity guaranteed- Fully normalized to 3NF โ no redundancy, no update anomalies
| Table | Rows | Description |
|---|---|---|
| users | XX | Registered buyers and sellers |
| products | XX | Product listings across N categories |
| orders | XX | Completed purchase transactions |
Countries covered: India, Japan, USA, Germany, China, Mexico Categories covered: Electronics, Fashion, Books, Photography, Sports
"How big is our platform? What are the core KPIs?"
| # | Question |
|---|---|
| 1 | Total users, products, orders, and revenue in one dashboard query |
| 2 | Active vs sold product ratio across the platform |
| 3 | Average order value + median order value |
| 4 | Platform coverage โ unique countries and market count |
| 5 | New user registrations โ this month vs last month |
"Who are our best sellers? Who is underperforming?"
| # | Question |
|---|---|
| 1 | Seller health report โ sell-through rate, revenue, tier classification |
| 2 | Top N sellers by revenue with market share percentage |
| 3 | Sellers with no completed sales โ dead accounts |
| 4 | Revenue concentration โ what % of revenue comes from top 3 sellers? |
| 5 | Seller ranking with RANK() per country |
"Who are our buyers? How do they spend?"
| # | Question |
|---|---|
| 1 | Buyer segmentation โ Whale / High / Mid / Low value |
| 2 | Referred vs organic buyer spending comparison |
| 3 | Average spend by generation โ Teen / Gen Z / Millennial |
| 4 | Buyers who placed only one order โ churn risk |
| 5 | Top buyer per country |
"What's selling? What's sitting? What's overpriced?"
| # | Question |
|---|---|
| 1 | Price tier distribution โ Budget / Mid-range / Premium |
| 2 | Top product per category by price (RANK per partition) |
| 3 | Products priced above their category average |
| 4 | Conversion rate per category โ sold vs listed |
| 5 | Dead stock โ products with zero orders |
"Where is our revenue coming from? Where should we expand?"
| # | Question |
|---|---|
| 1 | Revenue and user count per country |
| 2 | Cross-country transaction flow matrix |
| 3 | Market classification โ Core / Growing / Emerging |
| 4 | APAC vs Europe vs Americas comparison |
| 5 | Country-wise user type pivot |
"What should we fix? Who should we target?"
| # | Question |
|---|---|
| 1 | Inactive users โ never bought, never sold |
| 2 | Buyers who haven't tried selling โ conversion opportunity |
| 3 | Underperforming categories โ low conversion rate |
| 4 | Referral program effectiveness โ referred vs organic LTV |
| 5 | Full opportunity summary with recommended actions |
(Fill this in with your actual query results โ your own words)
Finding 1 โ [Give it a title] [Write 2-3 sentences describing what you found and why it matters]
Finding 2 โ [Title] [Your insight here]
Finding 3 โ [Title] [Your insight here]
Finding 4 โ [Title] [Your insight here]
Finding 5 โ [Title] [Your insight here]
This project demonstrates the full SQL stack โ from foundations to expert level.
Foundations
SELECT,WHERE,ORDER BY,LIMIT,OFFSETGROUP BY+HAVING- Aggregate functions:
COUNT,SUM,AVG,MIN,MAX CASE WHENfor conditional logic and classification
Joins + Subqueries
INNER JOIN,LEFT JOIN,SELF JOIN, 3-table joins- Scalar subqueries, correlated subqueries, derived tables
EXISTS/NOT EXISTSโ NULL-safe filteringUNION,UNION ALLfor set operations
Advanced SQL
- Window functions:
ROW_NUMBER,RANK,DENSE_RANK - Offset functions:
LAG,LEAD,NTILE - Running totals + moving averages with
OVER(ROWS BETWEEN...) - CTEs (
WITHclause) โ multi-step analytical pipelines - Recursive CTEs โ referral chain traversal
Production Techniques
EXPLAIN+ index creation for query optimizationVIEWSโ reusable analytical layersSTORED PROCEDURESโ parameterized business logicTRANSACTIONS+ ACID propertiesNULLIF()+COALESCE()โ NULL-safe calculationsDECIMALoverFLOATfor monetary accuracy
WITH seller_listings AS (
SELECT seller_id,
COUNT(*) AS total_listed,
SUM(CASE WHEN status = 'sold' THEN 1 ELSE 0 END) AS total_sold,
COALESCE(SUM(o.amount), 0) AS revenue
FROM products p
LEFT JOIN orders o ON p.product_id = o.product_id
GROUP BY seller_id
)
SELECT
u.username,
u.country,
sl.total_listed,
sl.total_sold,
ROUND(sl.total_sold * 100.0 / NULLIF(sl.total_listed, 0), 1) AS sell_through_pct,
sl.revenue,
CASE
WHEN sl.revenue >= 50000 THEN 'Diamond'
WHEN sl.revenue >= 20000 THEN 'Gold'
WHEN sl.revenue >= 5000 THEN 'Silver'
WHEN sl.revenue > 0 THEN 'Bronze'
ELSE 'No Sales'
END AS seller_tier,
RANK() OVER (ORDER BY sl.revenue DESC) AS revenue_rank
FROM seller_listings sl
INNER JOIN users u ON sl.seller_id = u.user_id
ORDER BY sl.revenue DESC;SELECT
buyer.country AS from_country,
seller.country AS to_country,
COUNT(*) AS transactions,
SUM(o.amount) AS total_value,
CASE
WHEN buyer.country = seller.country THEN 'Domestic'
ELSE 'International'
END AS flow_type,
RANK() OVER (ORDER BY SUM(o.amount) DESC) AS value_rank
FROM orders o
INNER JOIN users buyer ON o.buyer_id = buyer.user_id
INNER JOIN products p ON o.product_id = p.product_id
INNER JOIN users seller ON p.seller_id = seller.user_id
GROUP BY buyer.country, seller.country
ORDER BY total_value DESC;CREATE OR REPLACE VIEW complete_user_profile AS
WITH seller_data AS (
SELECT p.seller_id,
COUNT(p.product_id) AS listings,
SUM(CASE WHEN p.status='sold' THEN 1 ELSE 0 END) AS sold_items,
COALESCE(SUM(o.amount), 0) AS seller_revenue
FROM products p LEFT JOIN orders o ON p.product_id = o.product_id
GROUP BY p.seller_id
),
buyer_data AS (
SELECT buyer_id, COUNT(*) AS total_orders, SUM(amount) AS total_spent
FROM orders GROUP BY buyer_id
)
SELECT
u.username, u.country, u.age,
CASE
WHEN u.age < 20 THEN 'Teen'
WHEN u.age BETWEEN 20 AND 26 THEN 'Gen Z'
WHEN u.age BETWEEN 27 AND 42 THEN 'Millennial'
ELSE 'Other'
END AS generation,
CASE
WHEN sd.listings > 0 AND bd.total_orders > 0 THEN 'Power User'
WHEN bd.total_orders > 0 THEN 'Buyer'
WHEN sd.listings > 0 THEN 'Seller'
ELSE 'Inactive'
END AS user_type,
COALESCE(sd.listings, 0) AS total_listings,
COALESCE(sd.seller_revenue, 0) AS seller_revenue,
COALESCE(bd.total_orders, 0) AS orders_placed,
COALESCE(bd.total_spent, 0) AS total_spent,
RANK() OVER (ORDER BY COALESCE(sd.seller_revenue, 0) DESC) AS seller_rank,
RANK() OVER (ORDER BY COALESCE(bd.total_spent, 0) DESC) AS buyer_rank
FROM users u
LEFT JOIN seller_data sd ON u.user_id = sd.seller_id
LEFT JOIN buyer_data bd ON u.user_id = bd.buyer_id;# 1. Clone the repo
git clone https://github.com/Prashant-4527/mercaridb-capstone.git
cd mercaridb-capstone
# 2. Open MySQL Workbench (or any MySQL client)
# 3. Run schema first
# schema/01_schema.sql โ creates all tables
# schema/02_seed_data.sql โ loads all data
# 4. Run any analysis file
# analysis/01_platform_overview.sql
# analysis/02_seller_analysis.sql
# ... etc.Requirements: MySQL 8.0+ ยท MySQL Workbench ยท Git
mercaridb-capstone/
โ
โโโ README.md
โ
โโโ schema/
โ โโโ 01_schema.sql โ CREATE TABLE statements (3NF design)
โ โโโ 02_seed_data.sql โ INSERT statements (realistic data)
โ
โโโ analysis/
โ โโโ 01_platform_overview.sql
โ โโโ 02_seller_analysis.sql
โ โโโ 03_buyer_behaviour.sql
โ โโโ 04_product_intelligence.sql
โ โโโ 05_market_analysis.sql
โ โโโ 06_growth_opportunities.sql
โ
โโโ views/
โ โโโ dashboard_views.sql โ Reusable analytical views
โ
โโโ advanced/
โ โโโ window_functions.sql
โ โโโ cte_pipelines.sql
โ โโโ stored_procedures.sql
โ
โโโ insights/
โโโ KEY_FINDINGS.md โ Plain-language business insights
| Project | Description |
|---|---|
| mercaridb-mysql-30days | 30-day structured SQL learning journey |
| Mercari-analytics-report | Earlier analytics report (Week 1-2 level) |
| EduTrack-oop-numpy | Python OOP + NumPy analytics system |
Prashant โ BCA Student @ Maharaja College Jaipur Self-directing a multi-year curriculum toward an AI Engineering role at Mercari Japan by 2028.
Stack: Python ยท MySQL ยท NumPy ยท Pandas (in progress) ยท DSA (daily) Languages: English ยท Hindi ยท Japanese (N4 โ N3) ยท German (A2) Target: METI IPA Internship 2027 โ Mercari Japan 2028 ๐ฏ๐ต
Built from scratch. Every query written by hand. No shortcuts. ใกใซใซใชใงๆฅๆฌใ็ฎๆใ๏ผ